<!DOCTYPE html><html class=split lang=en-US-x-hixie><script src=../link-fixup.js defer=""></script>
<!-- Mirrored from html.spec.whatwg.org/dev/canvas.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 10 Sep 2025 08:36:26 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<meta charset=utf-8><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name=viewport><title>HTML Standard, Edition for Web Developers</title><meta content=#3c790a name=theme-color><meta content="light dark" name=color-scheme><link rel=stylesheet href=../../resources.whatwg.org/standard-shared-with-dev.css crossorigin=""><link rel=icon href=https://resources.whatwg.org/logo.svg crossorigin=""><link rel=stylesheet href=styles.css crossorigin=""><script>
   function toggleStatus(div) {
     div.parentNode.classList.toggle('wrapped');
   }
   function setLinkFragment(link) {
     link.hash = location.hash;
   }
  </script><body>
  <script async="" src=search.js></script>
  
  
  <header id=head class="head with-buttons">
   <a href=https://whatwg.org/ class=logo><img width=100 alt=WHATWG crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/logo.svg height=100></a>
   
   <hgroup><h1><a rel=home href=index.html>HTML: The Living Standard</a></h1><p id=dev-edition-h2>Edition for Web Developers — Last Updated <span class=pubdate>10 September 2025</span></hgroup>
   

   <div id=search>
    <input placeholder="Search. Press '/'" autocomplete=off name=query id=query type=search>
    <ol id=results></ol>
   </div>
  </header>

  

  

  

  
  

  
  

  

  <nav><a href=scripting.html>← 4.12 Scripting</a> — <a href=index.html>Table of Contents</a> — <a href=custom-elements.html>4.13 Custom elements →</a></nav><ol class=toc><li><ol><li><ol><li><a href=canvas.html#the-canvas-element><span class=secno>4.12.5</span> The <code>canvas</code> element</a><ol><li><a href=canvas.html#2dcontext><span class=secno>4.12.5.1</span> The 2D rendering context</a><ol><li><a href=canvas.html#implementation-notes><span class=secno>4.12.5.1.1</span> Implementation notes</a><li><a href=canvas.html#the-canvas-settings><span class=secno>4.12.5.1.2</span> The canvas settings</a><li><a href=canvas.html#the-canvas-state><span class=secno>4.12.5.1.3</span> The canvas state</a><li><a href=canvas.html#line-styles><span class=secno>4.12.5.1.4</span> Line styles</a><li><a href=canvas.html#text-styles><span class=secno>4.12.5.1.5</span> Text styles</a><li><a href=canvas.html#building-paths><span class=secno>4.12.5.1.6</span> Building paths</a><li><a href=canvas.html#path2d-objects><span class=secno>4.12.5.1.7</span> <code>Path2D</code> objects</a><li><a href=canvas.html#transformations><span class=secno>4.12.5.1.8</span> Transformations</a><li><a href=canvas.html#image-sources-for-2d-rendering-contexts><span class=secno>4.12.5.1.9</span> Image sources for 2D rendering contexts</a><li><a href=canvas.html#fill-and-stroke-styles><span class=secno>4.12.5.1.10</span> Fill and stroke styles</a><li><a href=canvas.html#drawing-rectangles-to-the-bitmap><span class=secno>4.12.5.1.11</span> Drawing rectangles to the bitmap</a><li><a href=canvas.html#drawing-text-to-the-bitmap><span class=secno>4.12.5.1.12</span> Drawing text to the bitmap</a><li><a href=canvas.html#drawing-paths-to-the-canvas><span class=secno>4.12.5.1.13</span> Drawing paths to the canvas</a><li><a href=canvas.html#drawing-focus-rings-and-scrolling-paths-into-view><span class=secno>4.12.5.1.14</span> Drawing focus rings</a><li><a href=canvas.html#drawing-images><span class=secno>4.12.5.1.15</span> Drawing images</a><li><a href=canvas.html#pixel-manipulation><span class=secno>4.12.5.1.16</span> Pixel manipulation</a><li><a href=canvas.html#compositing><span class=secno>4.12.5.1.17</span> Compositing</a><li><a href=canvas.html#image-smoothing><span class=secno>4.12.5.1.18</span> Image smoothing</a><li><a href=canvas.html#shadows><span class=secno>4.12.5.1.19</span> Shadows</a><li><a href=canvas.html#filters><span class=secno>4.12.5.1.20</span> Filters</a><li><a href=canvas.html#working-with-externally-defined-svg-filters><span class=secno>4.12.5.1.21</span> Working with externally-defined SVG filters</a><li><a href=canvas.html#best-practices><span class=secno>4.12.5.1.22</span> Best practices</a><li><a href=canvas.html#examples><span class=secno>4.12.5.1.23</span> Examples</a></ol><li><a href=canvas.html#the-imagebitmap-rendering-context><span class=secno>4.12.5.2</span> The <code>ImageBitmap</code> rendering context</a><ol><li><a href=canvas.html#introduction-5><span class=secno>4.12.5.2.1</span> Introduction</a><li><a href=canvas.html#the-imagebitmaprenderingcontext-interface><span class=secno>4.12.5.2.2</span> The <code>ImageBitmapRenderingContext</code> interface</a></ol><li><a href=canvas.html#the-offscreencanvas-interface><span class=secno>4.12.5.3</span> The <code>OffscreenCanvas</code> interface</a><ol><li><a href=canvas.html#the-offscreen-2d-rendering-context><span class=secno>4.12.5.3.1</span> The offscreen 2D rendering context</a></ol><li><a href=canvas.html#serialising-bitmaps-to-a-file><span class=secno>4.12.5.4</span> Serializing bitmaps to a file</a><li><a href=canvas.html#premultiplied-alpha-and-the-2d-rendering-context><span class=secno>4.12.5.5</span> Premultiplied alpha and the 2D rendering context</a></ol></ol></ol></ol><h4 id=the-canvas-element><span class=secno>4.12.5</span> The <dfn id=canvas data-dfn-type=element><code>canvas</code></dfn> element<a href=#the-canvas-element class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas title="Use the HTML <canvas> element with either the canvas scripting API or the WebGL API to draw graphics and animations.">Element/canvas</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>1.5+</span></span><span class="safari yes"><span>Safari</span><span>2+</span></span><span class="chrome yes"><span>Chrome</span><span>1+</span></span><hr><span class="opera yes"><span>Opera</span><span>9+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>9+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>1+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>10.1+</span></span></div></div></div>

  <dl class=element><dt><a href=dom.html#concept-element-categories id=the-canvas-element:concept-element-categories>Categories</a>:<dd><a id=the-canvas-element:flow-content-2 href=dom.html#flow-content-2>Flow content</a>.<dd><a id=the-canvas-element:phrasing-content-2 href=dom.html#phrasing-content-2>Phrasing content</a>.<dd><a id=the-canvas-element:embedded-content-category href=dom.html#embedded-content-category>Embedded content</a>.<dd><a id=the-canvas-element:palpable-content-2 href=dom.html#palpable-content-2>Palpable content</a>.<dt><a href=dom.html#concept-element-contexts id=the-canvas-element:concept-element-contexts>Contexts in which this element can be used</a>:<dd>Where <a id=the-canvas-element:embedded-content-category-2 href=dom.html#embedded-content-category>embedded content</a> is expected.<dt><a href=dom.html#concept-element-content-model id=the-canvas-element:concept-element-content-model>Content model</a>:<dd><a id=the-canvas-element:transparent href=dom.html#transparent>Transparent</a>, but with no <a id=the-canvas-element:interactive-content-2 href=dom.html#interactive-content-2>interactive content</a> descendants except
   for <code id=the-canvas-element:the-a-element><a href=text-level-semantics.html#the-a-element>a</a></code> elements, <code id=the-canvas-element:the-img-element><a href=embedded-content.html#the-img-element>img</a></code> elements with
   <code id=the-canvas-element:attr-hyperlink-usemap><a href=image-maps.html#attr-hyperlink-usemap>usemap</a></code> attributes, <code id=the-canvas-element:the-button-element><a href=form-elements.html#the-button-element>button</a></code> elements,
   <code id=the-canvas-element:the-input-element><a href=input.html#the-input-element>input</a></code> elements whose <code id=the-canvas-element:attr-input-type><a href=input.html#attr-input-type>type</a></code> attribute are in
   the <a href="input.html#checkbox-state-(type=checkbox)" id="the-canvas-element:checkbox-state-(type=checkbox)">Checkbox</a> or <a href="input.html#radio-button-state-(type=radio)" id="the-canvas-element:radio-button-state-(type=radio)">Radio Button</a> states, <code id=the-canvas-element:the-input-element-2><a href=input.html#the-input-element>input</a></code> elements that are
   <a href=forms.html#concept-button id=the-canvas-element:concept-button>buttons</a>, and <code id=the-canvas-element:the-select-element><a href=form-elements.html#the-select-element>select</a></code> elements with a <code id=the-canvas-element:attr-select-multiple><a href=form-elements.html#attr-select-multiple>multiple</a></code> attribute or a <span>display size</span> greater than 1.<dt><a href=dom.html#concept-element-tag-omission id=the-canvas-element:concept-element-tag-omission>Tag omission in text/html</a>:<dd>Neither tag is omissible.<dt><a href=dom.html#concept-element-attributes id=the-canvas-element:concept-element-attributes>Content attributes</a>:<dd><a id=the-canvas-element:global-attributes href=dom.html#global-attributes>Global attributes</a><dd><code id=the-canvas-element:attr-canvas-width><a href=#attr-canvas-width>width</a></code> —  Horizontal dimension
     <dd><code id=the-canvas-element:attr-canvas-height><a href=#attr-canvas-height>height</a></code> —  Vertical dimension
     <dt><a href=dom.html#concept-element-accessibility-considerations id=the-canvas-element:concept-element-accessibility-considerations>Accessibility considerations</a>:<dd><a href=https://w3c.github.io/html-aria/#el-canvas>For authors</a>.<dd><a href=https://w3c.github.io/html-aam/#el-canvas>For implementers</a>.<dt><a href=dom.html#concept-element-dom id=the-canvas-element:concept-element-dom>DOM interface</a>:<dd>Uses <code>HTMLCanvasElement</code>.</dl>

  <p>The <code id=the-canvas-element:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element provides scripts with a resolution-dependent bitmap canvas,
  which can be used for rendering graphs, game graphics, art, or other visual images on the fly.</p>

  <p>Authors should not use the <code id=the-canvas-element:the-canvas-element-2><a href=#the-canvas-element>canvas</a></code> element in a document when a more suitable
  element is available. For example, it is inappropriate to use a <code id=the-canvas-element:the-canvas-element-3><a href=#the-canvas-element>canvas</a></code> element to
  render a page heading: if the desired presentation of the heading is graphically intense, it
  should be marked up using appropriate elements (typically <code id=the-canvas-element:the-h1,-h2,-h3,-h4,-h5,-and-h6-elements><a href=sections.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements>h1</a></code>) and then styled using
  CSS and supporting technologies such as <a href=https://dom.spec.whatwg.org/#concept-shadow-tree id=the-canvas-element:shadow-tree data-x-internal=shadow-tree>shadow trees</a>.</p>

  <p>When authors use the <code id=the-canvas-element:the-canvas-element-4><a href=#the-canvas-element>canvas</a></code> element, they must also provide content that, when
  presented to the user, conveys essentially the same function or purpose as the
  <code id=the-canvas-element:the-canvas-element-5><a href=#the-canvas-element>canvas</a></code>'s bitmap. This content may be placed as content of the <code id=the-canvas-element:the-canvas-element-6><a href=#the-canvas-element>canvas</a></code>
  element. The contents of the <code id=the-canvas-element:the-canvas-element-7><a href=#the-canvas-element>canvas</a></code> element, if any, are the element's <a id=the-canvas-element:fallback-content href=dom.html#fallback-content>fallback
  content</a>.</p>

  <hr>

  <p>In interactive visual media, if <span>scripting is enabled</span> for
  the <code id=the-canvas-element:the-canvas-element-8><a href=#the-canvas-element>canvas</a></code> element, and if support for <code id=the-canvas-element:the-canvas-element-9><a href=#the-canvas-element>canvas</a></code> elements has been enabled,
  then the <code id=the-canvas-element:the-canvas-element-10><a href=#the-canvas-element>canvas</a></code> element <a id=the-canvas-element:represents href=dom.html#represents>represents</a> <a id=the-canvas-element:embedded-content-category-3 href=dom.html#embedded-content-category>embedded content</a>
  consisting of a dynamically created image, the element's bitmap.</p>

  <p>In non-interactive, static, visual media, if the <code id=the-canvas-element:the-canvas-element-11><a href=#the-canvas-element>canvas</a></code> element has been
  previously associated with a rendering context (e.g. if the page was viewed in an interactive
  visual medium and is now being printed, or if some script that ran during the page layout process
  painted on the element), then the <code id=the-canvas-element:the-canvas-element-12><a href=#the-canvas-element>canvas</a></code> element <a id=the-canvas-element:represents-2 href=dom.html#represents>represents</a>
  <a id=the-canvas-element:embedded-content-category-4 href=dom.html#embedded-content-category>embedded content</a> with the element's current bitmap and size. Otherwise, the element
  represents its <a id=the-canvas-element:fallback-content-2 href=dom.html#fallback-content>fallback content</a> instead.</p>

  <p>In non-visual media, and in visual media if <span>scripting is
  disabled</span> for the <code id=the-canvas-element:the-canvas-element-13><a href=#the-canvas-element>canvas</a></code> element or if support for <code id=the-canvas-element:the-canvas-element-14><a href=#the-canvas-element>canvas</a></code> elements
  has been disabled, the <code id=the-canvas-element:the-canvas-element-15><a href=#the-canvas-element>canvas</a></code> element <a id=the-canvas-element:represents-3 href=dom.html#represents>represents</a> its <a id=the-canvas-element:fallback-content-3 href=dom.html#fallback-content>fallback
  content</a> instead.</p>

  
  <p>When a <code id=the-canvas-element:the-canvas-element-16><a href=#the-canvas-element>canvas</a></code> element <a id=the-canvas-element:represents-4 href=dom.html#represents>represents</a> <a id=the-canvas-element:embedded-content-category-5 href=dom.html#embedded-content-category>embedded content</a>, the
  user can still focus descendants of the <code id=the-canvas-element:the-canvas-element-17><a href=#the-canvas-element>canvas</a></code> element (in the <a id=the-canvas-element:fallback-content-4 href=dom.html#fallback-content>fallback
  content</a>). When an element is <a id=the-canvas-element:focused href=interaction.html#focused>focused</a>, it is the target of keyboard interaction
  events (even though the element itself is not visible). This allows authors to make an interactive
  canvas keyboard-accessible: authors should have a one-to-one mapping of interactive regions to <i id=the-canvas-element:focusable-area><a href=interaction.html#focusable-area>focusable areas</a></i> in the <a id=the-canvas-element:fallback-content-5 href=dom.html#fallback-content>fallback content</a>. (Focus has no
  effect on mouse interaction events.) <a href=references.html#refsUIEVENTS>[UIEVENTS]</a></p> 

  <p>An element whose nearest <code id=the-canvas-element:the-canvas-element-18><a href=#the-canvas-element>canvas</a></code> element ancestor is <span>being rendered</span>
  and <a id=the-canvas-element:represents-5 href=dom.html#represents>represents</a> <a id=the-canvas-element:embedded-content-category-6 href=dom.html#embedded-content-category>embedded content</a> is an element that is <dfn id=being-used-as-relevant-canvas-fallback-content>being used as
  relevant canvas fallback content</dfn>.</p>

  <hr>

  <p>The <code id=the-canvas-element:the-canvas-element-19><a href=#the-canvas-element>canvas</a></code> element has two attributes to control the size of the element's bitmap:
  <dfn data-dfn-for=canvas id=attr-canvas-width data-dfn-type=element-attr><code>width</code></dfn> and <dfn data-dfn-for=canvas id=attr-canvas-height data-dfn-type=element-attr><code>height</code></dfn>. These attributes,
  when specified, must have values that are <a href=common-microsyntaxes.html#valid-non-negative-integer id=the-canvas-element:valid-non-negative-integer>valid
  non-negative integers</a>.   The <code id=the-canvas-element:attr-canvas-width-2><a href=#attr-canvas-width>width</a></code>
  attribute defaults to 300, and the <code id=the-canvas-element:attr-canvas-height-2><a href=#attr-canvas-height>height</a></code> attribute
  defaults to 150.</p>

  <p>When setting the value of the <code id=the-canvas-element:attr-canvas-width-3><a href=#attr-canvas-width>width</a></code> or <code id=the-canvas-element:attr-canvas-height-3><a href=#attr-canvas-height>height</a></code> attribute, if the <span>context mode</span> of the <code id=the-canvas-element:the-canvas-element-20><a href=#the-canvas-element>canvas</a></code>
  element is set to <span>placeholder</span>, the
  user agent must throw an <a id=the-canvas-element:invalidstateerror href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a> <code id=the-canvas-element:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>
  and leave the attribute's value unchanged.</p>

  <p>The <a id=the-canvas-element:natural-dimensions href=https://drafts.csswg.org/css-images/#natural-dimensions data-x-internal=natural-dimensions>natural dimensions</a> of the <code id=the-canvas-element:the-canvas-element-21><a href=#the-canvas-element>canvas</a></code> element when it
  <a id=the-canvas-element:represents-6 href=dom.html#represents>represents</a> <a id=the-canvas-element:embedded-content-category-7 href=dom.html#embedded-content-category>embedded content</a> are equal to the dimensions of the
  element's bitmap.</p>

  <p>The user agent must use a square pixel density consisting of one pixel of image data per
  coordinate space unit for the bitmaps of a <code id=the-canvas-element:the-canvas-element-22><a href=#the-canvas-element>canvas</a></code> and its rendering contexts.</p>

  <p class=note>A <code id=the-canvas-element:the-canvas-element-23><a href=#the-canvas-element>canvas</a></code> element can be sized arbitrarily by a style sheet, its
  bitmap is then subject to the <a id="the-canvas-element:'object-fit'" href=https://drafts.csswg.org/css-images/#the-object-fit data-x-internal="'object-fit'">'object-fit'</a> CSS property.</p>

  

  <hr>

  <dl class=domintro><dt><code><var>context</var> = <var>canvas</var>.<span id=dom-canvas-getcontext>getContext</span>(<var>contextId</var> [, <var>options</var> ])</code><dd>
    <p>Returns an object that exposes an API for drawing on the canvas. <var>contextId</var>
    specifies the desired API: "<code>2d</code>", "<code>bitmaprenderer</code>", "<code>webgl</code>", "<code>webgl2</code>", or "<code>webgpu</code>". <var>options</var> is handled by that API.</p>

    <p>This specification defines the "<code>2d</code>" and "<code>bitmaprenderer</code>" contexts below. The WebGL
    specifications define the "<code>webgl</code>" and "<code>webgl2</code>" contexts. <cite>WebGPU</cite> defines the "<code>webgpu</code>" context. <a href=references.html#refsWEBGL>[WEBGL]</a> <a href=references.html#refsWEBGPU>[WEBGPU]</a></p>

    <p>Returns null if <var>contextId</var> is not supported, or if the canvas has already been
    initialized with another context type (e.g., trying to get a "<code>2d</code>" context after getting a "<code>webgl</code>" context).</p>
   </dl>

  

  <dl class=domintro><dt><code><var>url</var> = <var>canvas</var>.<span id=dom-canvas-todataurl>toDataURL</span>([ <var>type</var> [, <var>quality</var> ] ])</code><dd>
    <p>Returns a <a href=https://www.rfc-editor.org/rfc/rfc2397#section-2 id=the-canvas-element:data-protocol data-x-internal=data-protocol><code>data:</code> URL</a> for the image in the
    canvas.</p>

    <p>The first argument, if provided, controls the type of the image to be returned (e.g. PNG or
    JPEG). The default is "<code id=the-canvas-element:image/png><a href=indices.html#image/png>image/png</a></code>"; that type is also used if the given type isn't
    supported. The second argument applies if the type is an image format that supports variable
    quality (such as "<code id=the-canvas-element:image/jpeg><a href=indices.html#image/jpeg>image/jpeg</a></code>"), and is a number in the range 0.0 to 1.0 inclusive
    indicating the desired quality level for the resulting image.</p>

    <p>When trying to use types other than "<code id=the-canvas-element:image/png-2><a href=indices.html#image/png>image/png</a></code>", authors can check if the image
    was really returned in the requested format by checking to see if the returned string starts
    with one of the exact strings "<code>data:image/png,</code>" or "<code>data:image/png;</code>". If it does, the image is PNG, and thus the requested type was
    not supported. (The one exception to this is if the canvas has either no height or no width, in
    which case the result might simply be "<code>data:,</code>".)</p>
   <dt><code><var>canvas</var>.<span id=dom-canvas-toblob>toBlob</span>(<var>callback</var> [, <var>type</var> [, quality ] ])</code><dd>
    <p>Creates a <code id=the-canvas-element:blob><a data-x-internal=blob href=https://w3c.github.io/FileAPI/#dfn-Blob>Blob</a></code> object representing a file containing the image in the canvas,
    and invokes a callback with a handle to that object.</p>

    <p>The second argument, if provided, controls the type of the image to be returned (e.g. PNG or
    JPEG). The default is "<code id=the-canvas-element:image/png-3><a href=indices.html#image/png>image/png</a></code>"; that type is also used if the given type isn't
    supported. The third argument applies if the type is an image format that supports variable
    quality (such as "<code id=the-canvas-element:image/jpeg-2><a href=indices.html#image/jpeg>image/jpeg</a></code>"), and is a number in the range 0.0 to 1.0 inclusive
    indicating the desired quality level for the resulting image.</p>
   <dt><code><var>canvas</var>.<span id=dom-canvas-transfercontroltooffscreen>transferControlToOffscreen</span>()</code><dd>
    <p>Returns a newly created <code>OffscreenCanvas</code> object that uses the
    <code id=the-canvas-element:the-canvas-element-24><a href=#the-canvas-element>canvas</a></code> element as a placeholder. Once the <code id=the-canvas-element:the-canvas-element-25><a href=#the-canvas-element>canvas</a></code> element has become a
    placeholder for an <code>OffscreenCanvas</code> object, its natural size can no longer be
    changed, and it cannot have a rendering context. The content of the placeholder canvas is
    updated on the <code>OffscreenCanvas</code>'s <span>relevant agent</span>'s <a href=webappapis.html#concept-agent-event-loop id=the-canvas-element:concept-agent-event-loop>event loop</a>'s <span>update the rendering</span>
    steps.</p>
   </dl>

  


  <h5 id=2dcontext><span class=secno>4.12.5.1</span> The 2D rendering context<a href=#2dcontext class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D title="The CanvasRenderingContext2D interface, part of the Canvas API, provides the 2D rendering context for the drawing surface of a <canvas> element. It is used for drawing shapes, text, images, and other objects.">CanvasRenderingContext2D</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>1.5+</span></span><span class="safari yes"><span>Safari</span><span>2+</span></span><span class="chrome yes"><span>Chrome</span><span>1+</span></span><hr><span class="opera yes"><span>Opera</span><span>9+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>9+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>10.1+</span></span></div></div></div>

  

  

 

  

  <dl class=domintro><dt><code><var>context</var> = <var>canvas</var>.<a href=#dom-canvas-getcontext id=2dcontext:dom-canvas-getcontext>getContext</a>('2d' [, { [ <a href=#dom-canvasrenderingcontext2dsettings-alpha id=2dcontext:dom-canvasrenderingcontext2dsettings-alpha>alpha</a>: true ] [, <a href=#dom-canvasrenderingcontext2dsettings-desynchronized id=2dcontext:dom-canvasrenderingcontext2dsettings-desynchronized>desynchronized</a>: false ] [, <a href=#dom-canvasrenderingcontext2dsettings-colorspace id=2dcontext:dom-canvasrenderingcontext2dsettings-colorspace>colorSpace</a>: 'srgb'] [, <a href=#dom-canvasrenderingcontext2dsettings-willreadfrequently id=2dcontext:dom-canvasrenderingcontext2dsettings-willreadfrequently>willReadFrequently</a>: false ]} ])</code><dd>
    <p>Returns a <code>CanvasRenderingContext2D</code> object that is permanently bound to a
    particular <code id=2dcontext:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element.</p>

    <p>If the <code id=2dcontext:dom-canvasrenderingcontext2dsettings-alpha-2><a href=#dom-canvasrenderingcontext2dsettings-alpha>alpha</a></code> member is
    false, then the context is forced to always be opaque.</p>

    <p>If the <code id=2dcontext:dom-canvasrenderingcontext2dsettings-desynchronized-2><a href=#dom-canvasrenderingcontext2dsettings-desynchronized>desynchronized</a></code> member is
    true, then the context might be <a href=#concept-canvas-desynchronized id=2dcontext:concept-canvas-desynchronized>desynchronized</a>.</p>

    <p>The <code id=2dcontext:dom-canvasrenderingcontext2dsettings-colorspace-2><a href=#dom-canvasrenderingcontext2dsettings-colorspace>colorSpace</a></code> member
    specifies the <a href=#concept-canvas-color-space id=2dcontext:concept-canvas-color-space>color space</a> of the rendering
    context.</p>

    <p>The <code id=2dcontext:dom-canvasrenderingcontext2dsettings-colortype><a href=#dom-canvasrenderingcontext2dsettings-colortype>colorType</a></code> member
    specifies the <a href=#concept-canvas-color-type id=2dcontext:concept-canvas-color-type>color type</a> of the rendering
    context.</p>

    <p>If the <code id=2dcontext:dom-canvasrenderingcontext2dsettings-willreadfrequently-2><a href=#dom-canvasrenderingcontext2dsettings-willreadfrequently>willReadFrequently</a></code>
    member is true, then the context is marked for <a href=#concept-canvas-will-read-frequently id=2dcontext:concept-canvas-will-read-frequently>readback optimization</a>.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-canvas>canvas</span></code><dd><p>Returns the <code id=2dcontext:the-canvas-element-2><a href=#the-canvas-element>canvas</a></code> element.<dt><code><var>attributes</var> = <var>context</var>.<a href=#dom-context-2d-canvas-getcontextattributes id=2dcontext:dom-context-2d-canvas-getcontextattributes>getContextAttributes</a>()</code><dd>
    <p>Returns an object whose:</p>

    <ul><li><code id=2dcontext:concept-canvas-alpha><a href=#concept-canvas-alpha>alpha</a></code> member is true if the context has an alpha
     component that is not 1.0; otherwise false.<li><code id=2dcontext:dom-canvasrenderingcontext2dsettings-desynchronized-3><a href=#dom-canvasrenderingcontext2dsettings-desynchronized>desynchronized</a></code>
     member is true if the context can be <a href=#concept-canvas-desynchronized id=2dcontext:concept-canvas-desynchronized-2>desynchronized</a>.<li><code id=2dcontext:dom-canvasrenderingcontext2dsettings-colorspace-3><a href=#dom-canvasrenderingcontext2dsettings-colorspace>colorSpace</a></code> member is
     a string indicating the context's <a href=#concept-canvas-color-space id=2dcontext:concept-canvas-color-space-2>color
     space</a>.<li><code id=2dcontext:dom-canvasrenderingcontext2dsettings-colortype-2><a href=#dom-canvasrenderingcontext2dsettings-colortype>colorType</a></code> member is
     a string indicating the context's <a href=#concept-canvas-color-type id=2dcontext:concept-canvas-color-type-2>color
     type</a>.<li><code id=2dcontext:dom-canvasrenderingcontext2dsettings-willreadfrequently-3><a href=#dom-canvasrenderingcontext2dsettings-willreadfrequently>willReadFrequently</a></code>
     member is true if the context is marked for <a href=#concept-canvas-will-read-frequently id=2dcontext:concept-canvas-will-read-frequently-2>readback
     optimization</a>.</ul>
   </dl>

  

  <hr>

  <p>The <code>PredefinedColorSpace</code> enumeration is used to specify the <a href=#concept-canvas-color-space id=2dcontext:concept-canvas-color-space-3>color space</a> of the canvas's backing store.</p>

  <p>The "<dfn data-dfn-for=PredefinedColorSpace id=dom-predefinedcolorspace-srgb data-dfn-type=enum-value><code>srgb</code></dfn>" value indicates the <a id="2dcontext:'srgb'" href=https://drafts.csswg.org/css-color/#valdef-color-srgb data-x-internal="'srgb'">'srgb'</a>
  color space.</p>

  <p>The "<dfn data-dfn-for=PredefinedColorSpace id=dom-predefinedcolorspace-display-p3 data-dfn-type=enum-value><code>display-p3</code></dfn>" value indicates the
  <a id="2dcontext:'display-p3'" href=https://drafts.csswg.org/css-color/#valdef-color-display-p3 data-x-internal="'display-p3'">'display-p3'</a> color space.</p>

  <p class=note>The algorithm for converting between color spaces can be found in the
  <a id=2dcontext:converting-colors href=https://drafts.csswg.org/css-color/#color-conversion data-x-internal=converting-colors>Converting Colors</a> section of <cite>CSS Color</cite>. <a href=references.html#refsCSSCOLOR>[CSSCOLOR]</a></p>

  <hr>

  <p>The <code>CanvasColorType</code> enumeration is used to specify the <a href=#concept-canvas-color-type id=2dcontext:concept-canvas-color-type-3>color type</a> of the canvas's backing store.</p>

  <p>The "<dfn data-dfn-for=CanvasColorType id=dom-canvascolortype-unorm8 data-dfn-type=enum-value><code>unorm8</code></dfn>" value indicates that the type
  for all color components is 8-bit unsigned normalized.</p>

  <p>The "<dfn data-dfn-for=CanvasColorType id=dom-canvascolortype-float16 data-dfn-type=enum-value><code>float16</code></dfn>" value indicates that the type
  for all color components is 16-bit floating point.</p>

  <hr>

  <p>The <code>CanvasFillRule</code> enumeration is used to select the <dfn id=fill-rule>fill rule</dfn>
  algorithm by which to determine if a point is inside or outside a path.</p>

  <p>The "<dfn data-dfn-for=CanvasFillRule id=dom-context-2d-fillrule-nonzero data-dfn-type=enum-value><code>nonzero</code></dfn>" value indicates the nonzero winding
  rule, wherein

     a point is considered to be outside a shape if the number of times a half-infinite straight
     line drawn from that point crosses the shape's path going in one direction is equal to the
     number of times it crosses the path going in the other direction.

  </p>


  <p>The "<dfn data-dfn-for=CanvasFillRule id=dom-context-2d-fillrule-evenodd data-dfn-type=enum-value><code>evenodd</code></dfn>" value indicates the even-odd rule,
  wherein

     a point is considered to be outside a shape if the number of times a half-infinite straight
     line drawn from that point crosses the shape's path is even.

  </p>

  <p>If a point is not outside a shape, it is inside the shape.</p>


  <hr>

  <p>The <code>ImageSmoothingQuality</code> enumeration is used to express a preference for the
  interpolation quality to use when smoothing images.</p>

  <p>The "<dfn data-dfn-for=ImageSmoothingQuality id=dom-context-2d-imagesmoothingquality-low data-dfn-type=enum-value><code>low</code></dfn>" value indicates a preference
  for a low level of image interpolation quality. Low-quality image interpolation may be more
  computationally efficient than higher settings.</p>

  <p>The "<dfn data-dfn-for=ImageSmoothingQuality id=dom-context-2d-imagesmoothingquality-medium data-dfn-type=enum-value><code>medium</code></dfn>" value indicates a
  preference for a medium level of image interpolation quality.</p>

  <p>The "<dfn data-dfn-for=ImageSmoothingQuality id=dom-context-2d-imagesmoothingquality-high data-dfn-type=enum-value><code>high</code></dfn>" value indicates a preference
  for a high level of image interpolation quality. High-quality image interpolation may be more
  computationally expensive than lower settings.</p>

  <p class=note>Bilinear scaling is an example of a relatively fast, lower-quality image-smoothing
  algorithm. Bicubic or Lanczos scaling are examples of image-smoothing algorithms that produce
  higher-quality output. This specification does not mandate that specific interpolation algorithms
  be used.</p>


  <h6 id=implementation-notes><span class=secno>4.12.5.1.1</span> Implementation notes<a href=#implementation-notes class=self-link></a></h6>

  

  <p>The <a href=#output-bitmap id=implementation-notes:output-bitmap>output bitmap</a>, when it is not directly displayed by the user agent,
  implementations can, instead of updating this bitmap, merely remember the sequence of drawing
  operations that have been applied to it until such time as the bitmap's actual data is needed
  (for example because of a call to <code id=implementation-notes:dom-context-2d-drawimage><a href=#dom-context-2d-drawimage>drawImage()</a></code>, or
  the <code id=implementation-notes:dom-createimagebitmap><a href=imagebitmap-and-animations.html#dom-createimagebitmap>createImageBitmap()</a></code> factory method). In many
  cases, this will be more memory efficient.</p>

  <p>The bitmap of a <code id=implementation-notes:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element is the one bitmap that's pretty much always going
  to be needed in practice. The <a href=#output-bitmap id=implementation-notes:output-bitmap-2>output bitmap</a> of a rendering context, when it has one,
  is always just an alias to a <code id=implementation-notes:the-canvas-element-2><a href=#the-canvas-element>canvas</a></code> element's bitmap.</p>

  <p>Additional bitmaps are sometimes needed, e.g. to enable fast drawing when the canvas is being
  painted at a different size than its <a href=https://drafts.csswg.org/css-images/#natural-dimensions id=implementation-notes:natural-dimensions data-x-internal=natural-dimensions>natural size</a>,
  or to enable double buffering so that graphics updates, like page scrolling for example, can be
  processed concurrently while canvas draw commands are being executed.</p>

  <h6 id=the-canvas-settings><span class=secno>4.12.5.1.2</span> The canvas settings<a href=#the-canvas-settings class=self-link></a></h6>

  <p>A <code>CanvasSettings</code> object has an <dfn id=output-bitmap>output bitmap</dfn> that is initialized when
  the object is created.</p>

  <p>The <a href=#output-bitmap id=the-canvas-settings:output-bitmap>output bitmap</a> has an <span>origin-clean</span> flag, which can be set to true or false.
  Initially, when one of these bitmaps is created, its <span>origin-clean</span> flag must be set to true.</p>

  <p>The <code>CanvasSettings</code> object also has an <dfn id=concept-canvas-alpha>alpha</dfn> boolean. When a <code>CanvasSettings</code> object's
  <a href=#concept-canvas-alpha id=the-canvas-settings:concept-canvas-alpha>alpha</a> is false, then its alpha component must be fixed
  to 1.0 (fully opaque) for all pixels, and attempts to change the alpha component of any pixel must
  be silently ignored.</p>

  <p class=note>Thus, the bitmap of such a context starts off as <a id=the-canvas-settings:opaque-black href=https://drafts.csswg.org/css-color/#opaque-black data-x-internal=opaque-black>opaque black</a> instead
  of <a id=the-canvas-settings:transparent-black href=https://drafts.csswg.org/css-color/#transparent-black data-x-internal=transparent-black>transparent black</a>; <code id=the-canvas-settings:dom-context-2d-clearrect><a href=#dom-context-2d-clearrect>clearRect()</a></code>
  always results in <a id=the-canvas-settings:opaque-black-2 href=https://drafts.csswg.org/css-color/#opaque-black data-x-internal=opaque-black>opaque black</a> pixels, every fourth byte from <code id=the-canvas-settings:dom-context-2d-getimagedata><a href=#dom-context-2d-getimagedata>getImageData()</a></code> is always 255, the <code id=the-canvas-settings:dom-context-2d-putimagedata><a href=#dom-context-2d-putimagedata>putImageData()</a></code> method effectively ignores every fourth
  byte in its input, and so on. However, the alpha component of styles and images drawn onto the
  canvas are still honoured up to the point where they would impact the <a href=#output-bitmap id=the-canvas-settings:output-bitmap-2>output bitmap</a>'s
  alpha component; for instance, drawing a 50% transparent white square on a freshly created
  <a href=#output-bitmap id=the-canvas-settings:output-bitmap-3>output bitmap</a> with its <a href=#concept-canvas-alpha id=the-canvas-settings:concept-canvas-alpha-2>alpha</a> set to false
  will result in a fully-opaque gray square.</p>

  <p>The <code>CanvasSettings</code> object also has a <dfn id=concept-canvas-desynchronized>desynchronized</dfn> boolean. When a
  <code>CanvasSettings</code> object's <a href=#concept-canvas-desynchronized id=the-canvas-settings:concept-canvas-desynchronized>desynchronized</a> is true, then the user agent may
  optimize the rendering of the canvas to reduce the latency, as measured from input events to
  rasterization, by desynchronizing the canvas paint cycle from the event loop, bypassing the
  ordinary user agent rendering algorithm, or both. Insofar as this mode involves bypassing the
  usual paint mechanisms, rasterization, or both, it might introduce visible tearing artifacts.</p>

  <p class=note>The user agent usually renders on a buffer which is not being displayed, quickly
  swapping it and the one being scanned out for presentation; the former buffer is called back
  buffer and the latter <i>front buffer</i>. A popular technique for reducing latency is called
  front buffer rendering, also known as <i>single buffer</i> rendering, where rendering happens in
  parallel and racily with the scanning out process. This technique reduces the latency at the price
  of potentially introducing tearing artifacts and can be used to implement in total or part of the
  <a href=#concept-canvas-desynchronized id=the-canvas-settings:concept-canvas-desynchronized-2>desynchronized</a> boolean.
  <a href=references.html#refsMULTIPLEBUFFERING>[MULTIPLEBUFFERING]</a></p>

  <p class=note>The <a href=#concept-canvas-desynchronized id=the-canvas-settings:concept-canvas-desynchronized-3>desynchronized</a> boolean can
  be useful when implementing certain kinds of applications, such as drawing applications, where the
  latency between input and rasterization is critical.</p>

  <p>The <code>CanvasSettings</code> object also has a <dfn id=concept-canvas-will-read-frequently>will read frequently</dfn> boolean. When a
  <code>CanvasSettings</code> object's <a href=#concept-canvas-will-read-frequently id=the-canvas-settings:concept-canvas-will-read-frequently>will read
  frequently</a> is true, the user agent may optimize the canvas for readback operations.</p>

  <p class=note>On most devices the user agent needs to decide whether to store the canvas's
  <a href=#output-bitmap id=the-canvas-settings:output-bitmap-4>output bitmap</a> on the GPU (this is also called "hardware accelerated"), or on the CPU
  (also called "software"). Most rendering operations are more performant for accelerated canvases,
  with the major exception being readback with <code id=the-canvas-settings:dom-context-2d-getimagedata-2><a href=#dom-context-2d-getimagedata>getImageData()</a></code>, <code id=the-canvas-settings:dom-canvas-todataurl><a href=#dom-canvas-todataurl>toDataURL()</a></code>, or <code id=the-canvas-settings:dom-canvas-toblob><a href=#dom-canvas-toblob>toBlob()</a></code>. <code>CanvasSettings</code> objects with <a href=#concept-canvas-will-read-frequently id=the-canvas-settings:concept-canvas-will-read-frequently-2>will read frequently</a> equal to true tell the
  user agent that the webpage is likely to perform many readback operations and that it is
  advantageous to use a software canvas.</p>

  <p>The <code>CanvasSettings</code> object also has a <dfn id=concept-canvas-color-space>color space</dfn> setting of type
  <code>PredefinedColorSpace</code>. The <code>CanvasSettings</code> object's <a href=#concept-canvas-color-space id=the-canvas-settings:concept-canvas-color-space>color space</a> indicates the color space for the
  <a href=#output-bitmap id=the-canvas-settings:output-bitmap-5>output bitmap</a>.</p>

  <p>The <code>CanvasSettings</code> object also has a <dfn id=concept-canvas-color-type>color type</dfn> setting of type
  <code>CanvasColorType</code>. The <code>CanvasSettings</code> object's <a href=#concept-canvas-color-type id=the-canvas-settings:concept-canvas-color-type>color type</a> indicates the data type of the
  color and alpha components of the pixels of the <a href=#output-bitmap id=the-canvas-settings:output-bitmap-6>output bitmap</a>.</p>

  <p>To <dfn id=canvas-setting-init-bitmap>initialize a <code>CanvasSettings</code> output
  bitmap</dfn>, given a <code>CanvasSettings</code> <var>context</var> and a
  <code>CanvasRenderingContext2DSettings</code> <var>settings</var>:</p>

  <ol><li><p>Set <var>context</var>'s <a href=#concept-canvas-alpha id=the-canvas-settings:concept-canvas-alpha-3>alpha</a> to
   <var>settings</var>["<dfn data-dfn-for=CanvasRenderingContext2DSettings id=dom-canvasrenderingcontext2dsettings-alpha data-dfn-type=dict-member><code>alpha</code></dfn>"].<li><p>Set <var>context</var>'s <a href=#concept-canvas-desynchronized id=the-canvas-settings:concept-canvas-desynchronized-4>desynchronized</a> to <var>settings</var>["<dfn data-dfn-for=CanvasRenderingContext2DSettings id=dom-canvasrenderingcontext2dsettings-desynchronized data-dfn-type=dict-member><code>desynchronized</code></dfn>"].<li><p>Set <var>context</var>'s <a href=#concept-canvas-color-space id=the-canvas-settings:concept-canvas-color-space-2>color space</a> to
   <var>settings</var>["<dfn data-dfn-for=CanvasRenderingContext2DSettings id=dom-canvasrenderingcontext2dsettings-colorspace data-dfn-type=dict-member><code>colorSpace</code></dfn>"].<li><p>Set <var>context</var>'s <a href=#concept-canvas-color-type id=the-canvas-settings:concept-canvas-color-type-2>color type</a> to
   <var>settings</var>["<dfn data-dfn-for=CanvasRenderingContext2DSettings id=dom-canvasrenderingcontext2dsettings-colortype data-dfn-type=dict-member><code>colorType</code></dfn>"].<li><p>Set <var>context</var>'s <a href=#concept-canvas-will-read-frequently id=the-canvas-settings:concept-canvas-will-read-frequently-3>will read
   frequently</a> to <var>settings</var>["<dfn data-dfn-for=CanvasRenderingContext2DSettings id=dom-canvasrenderingcontext2dsettings-willreadfrequently data-dfn-type=dict-member><code>willReadFrequently</code></dfn>"].</ol>

  <p>The <dfn data-dfn-for=CanvasSettings id=dom-context-2d-canvas-getcontextattributes data-dfn-type=method><code>getContextAttributes()</code></dfn> method
  steps are to return «[ "<code id=the-canvas-settings:dom-canvasrenderingcontext2dsettings-alpha><a href=#dom-canvasrenderingcontext2dsettings-alpha>alpha</a></code>" →
  <a id=the-canvas-settings:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-canvas-alpha id=the-canvas-settings:concept-canvas-alpha-4>alpha</a>, "<code id=the-canvas-settings:dom-canvasrenderingcontext2dsettings-desynchronized><a href=#dom-canvasrenderingcontext2dsettings-desynchronized>desynchronized</a></code>" →
  <a id=the-canvas-settings:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-canvas-desynchronized id=the-canvas-settings:concept-canvas-desynchronized-5>desynchronized</a>, "<code id=the-canvas-settings:dom-canvasrenderingcontext2dsettings-colorspace><a href=#dom-canvasrenderingcontext2dsettings-colorspace>colorSpace</a></code>" → <a id=the-canvas-settings:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
  <a href=#concept-canvas-color-space id=the-canvas-settings:concept-canvas-color-space-3>color space</a>, "<code id=the-canvas-settings:dom-canvasrenderingcontext2dsettings-colortype><a href=#dom-canvasrenderingcontext2dsettings-colortype>colorType</a></code>" → <a id=the-canvas-settings:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
  <a href=#concept-canvas-color-type id=the-canvas-settings:concept-canvas-color-type-3>color type</a>, "<code id=the-canvas-settings:dom-canvasrenderingcontext2dsettings-willreadfrequently><a href=#dom-canvasrenderingcontext2dsettings-willreadfrequently>willReadFrequently</a></code>" →
  <a id=the-canvas-settings:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-canvas-will-read-frequently id=the-canvas-settings:concept-canvas-will-read-frequently-4>will read frequently</a>
  ]».</p>

  <h6 id=the-canvas-state><span class=secno>4.12.5.1.3</span> The canvas state<a href=#the-canvas-state class=self-link></a></h6>

  <p>Objects that implement the <code>CanvasState</code> interface maintain a stack of drawing
  states. <dfn id=drawing-state>Drawing states</dfn> consist of:</p>

  <ul><li><p>The current <a href=#transformations id=the-canvas-state:transformations>transformation
   matrix</a>.<li><p>The current <span>clipping region</span>.<li><p>The current <span>letter
   spacing</span>, <span>word spacing</span>,
   <span>fill style</span>, <span>stroke style</span>, <span>filter</span>, <span>global alpha</span>, <span>compositing and blending operator</span>, and <span>shadow color</span>.<li><p>The current values of the following attributes: <code id=the-canvas-state:dom-context-2d-linewidth><a href=#dom-context-2d-linewidth>lineWidth</a></code>, <code id=the-canvas-state:dom-context-2d-linecap><a href=#dom-context-2d-linecap>lineCap</a></code>, <code id=the-canvas-state:dom-context-2d-linejoin><a href=#dom-context-2d-linejoin>lineJoin</a></code>, <code id=the-canvas-state:dom-context-2d-miterlimit><a href=#dom-context-2d-miterlimit>miterLimit</a></code>, <code id=the-canvas-state:dom-context-2d-linedashoffset><a href=#dom-context-2d-linedashoffset>lineDashOffset</a></code>, <code id=the-canvas-state:dom-context-2d-shadowoffsetx><a href=#dom-context-2d-shadowoffsetx>shadowOffsetX</a></code>, <code id=the-canvas-state:dom-context-2d-shadowoffsety><a href=#dom-context-2d-shadowoffsety>shadowOffsetY</a></code>, <code id=the-canvas-state:dom-context-2d-shadowblur><a href=#dom-context-2d-shadowblur>shadowBlur</a></code>, <code id=the-canvas-state:dom-context-2d-lang><a href=#dom-context-2d-lang>lang</a></code>, <code id=the-canvas-state:dom-context-2d-font><a href=#dom-context-2d-font>font</a></code>, <code id=the-canvas-state:dom-context-2d-textalign><a href=#dom-context-2d-textalign>textAlign</a></code>, <code id=the-canvas-state:dom-context-2d-textbaseline><a href=#dom-context-2d-textbaseline>textBaseline</a></code>, <code id=the-canvas-state:dom-context-2d-direction><a href=#dom-context-2d-direction>direction</a></code>, <code id=the-canvas-state:dom-context-2d-fontkerning><a href=#dom-context-2d-fontkerning>fontKerning</a></code>, <code id=the-canvas-state:dom-context-2d-fontstretch><a href=#dom-context-2d-fontstretch>fontStretch</a></code>, <code id=the-canvas-state:dom-context-2d-fontvariantcaps><a href=#dom-context-2d-fontvariantcaps>fontVariantCaps</a></code>, <code id=the-canvas-state:dom-context-2d-textrendering><a href=#dom-context-2d-textrendering>textRendering</a></code>, <code id=the-canvas-state:dom-context-2d-imagesmoothingenabled><a href=#dom-context-2d-imagesmoothingenabled>imageSmoothingEnabled</a></code>, <code id=the-canvas-state:dom-context-2d-imagesmoothingquality><a href=#dom-context-2d-imagesmoothingquality>imageSmoothingQuality</a></code>.<li><p>The current <span>dash list</span>.</ul>

  <p class=note>The rendering context's bitmaps are not part of the drawing state, as they
  depend on whether and how the rendering context is bound to a <code id=the-canvas-state:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element.</p>

  <p>Objects that implement the <code>CanvasState</code> mixin have a <dfn id=concept-canvas-context-lost>context lost</dfn> boolean, that is initialized to false
  when the object is created. The <a href=#concept-canvas-context-lost id=the-canvas-state:concept-canvas-context-lost>context lost</a>
  value is updated in the <span>context lost steps</span>.</p>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-save>save</span>()</code><dd><p>Pushes the current state onto the stack.<dt><code><var>context</var>.<span id=dom-context-2d-restore>restore</span>()</code><dd><p>Pops the top state on the stack, restoring the context to that state.<dt><code><var>context</var>.<span id=dom-context-2d-reset>reset</span>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/reset title="The CanvasRenderingContext2D.reset() method of the Canvas 2D API resets the rendering context to its default state, allowing it to be reused for drawing something else without having to explicitly reset all the properties.">CanvasRenderingContext2D/reset</a><div class=support><span class="firefox yes"><span>Firefox</span><span>113+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D#canvasrenderingcontext2d.reset title="The OffscreenCanvasRenderingContext2D interface is a CanvasRenderingContext2D rendering context for drawing to the bitmap of an OffscreenCanvas object. It is similar to the CanvasRenderingContext2D object, with the following differences:">OffscreenCanvasRenderingContext2D#canvasrenderingcontext2d.reset</a><div class=support><span class="firefox yes"><span>Firefox</span><span>113+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><p>Resets the rendering context, which includes the backing buffer, the drawing state stack,
   path, and styles.<dt><code><var>context</var>.<span id=dom-context-2d-iscontextlost>isContextLost</span>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in one engine only." class=less-than-two-engines-flag>⚠</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isContextLost title="The CanvasRenderingContext2D.isContextLost() method of the Canvas 2D API returns true if the rendering context is lost (and has not yet been reset). This might occur due to driver crashes, running out of memory, and so on.">CanvasRenderingContext2D/isContextLost</a><p class=less-than-two-engines-text>Support in one engine only.<div class=support><span class="firefox no"><span>Firefox</span><span>No</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><p>Returns true if the rendering context was lost. Context loss can occur due to driver
   crashes, running out of memory, etc. In these cases, the canvas loses its backing storage and
   takes steps to <span>reset the rendering context to its default state</span>.</dl>

  

  <h6 id=line-styles><span class=secno>4.12.5.1.4</span> Line styles<a href=#line-styles class=self-link></a></h6>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-linewidth>lineWidth</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-linewidth id=line-styles:dom-context-2d-linewidth>lineWidth</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current line width.</p>

    <p>Can be set, to change the line width. Values that are not finite values greater than zero are
    ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-linecap>lineCap</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-linecap id=line-styles:dom-context-2d-linecap>lineCap</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current line cap style.</p>

    <p>Can be set, to change the line cap style.</p>

    <p>The possible line cap styles are "<code>butt</code>", "<code>round</code>", and "<code>square</code>". Other values are ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-linejoin>lineJoin</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-linejoin id=line-styles:dom-context-2d-linejoin>lineJoin</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current line join style.</p>

    <p>Can be set, to change the line join style.</p>

    <p>The possible line join styles are "<code>bevel</code>", "<code>round</code>", and "<code>miter</code>". Other values are ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-miterlimit>miterLimit</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-miterlimit id=line-styles:dom-context-2d-miterlimit>miterLimit</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current miter limit ratio.</p>

    <p>Can be set, to change the miter limit ratio. Values that are not finite values greater than
    zero are ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-setlinedash>setLineDash</span>(<var>segments</var>)</code><dt><code><var>styles</var>.<a href=#dom-context-2d-setlinedash id=line-styles:dom-context-2d-setlinedash>setLineDash</a>(<var>segments</var>)</code><dd>
    <p>Sets the current line dash pattern (as used when stroking). The argument is a list of
    distances for which to alternately have the line on and the line off.</p>
   <dt><code><var>segments</var> = <var>context</var>.<span id=dom-context-2d-getlinedash>getLineDash</span>()</code><dt><code><var>segments</var> = <var>styles</var>.<a href=#dom-context-2d-getlinedash id=line-styles:dom-context-2d-getlinedash>getLineDash</a>()</code><dd>
    <p>Returns a copy of the current line dash pattern. The array returned will always have an even
    number of entries (i.e. the pattern is normalized).</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-linedashoffset>lineDashOffset</span></code><dt><code><var>styles</var>.<a href=#dom-context-2d-linedashoffset id=line-styles:dom-context-2d-linedashoffset>lineDashOffset</a></code><dd>
    <p>Returns the phase offset (in the same units as the line dash pattern).</p>

    <p>Can be set, to change the phase offset. Values that are not finite values are ignored.</p>
   </dl>

  


  <h6 id=text-styles><span class=secno>4.12.5.1.5</span> Text styles<a href=#text-styles class=self-link></a></h6>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-lang>lang</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-lang id=text-styles:dom-context-2d-lang>lang</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current language setting.</p>

    <p>Can be set to a BCP 47 language tag, the empty string, or "<code>inherit</code>", to change the language used when
    resolving fonts. "<code>inherit</code>" takes the language
    from the <code id=text-styles:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element's language, or the associated <a id=text-styles:document-element href=https://dom.spec.whatwg.org/#document-element data-x-internal=document-element>document
    element</a> when there is no <code id=text-styles:the-canvas-element-2><a href=#the-canvas-element>canvas</a></code> element.</p>

    <p>The default is "<code>inherit</code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-font>font</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-font id=text-styles:dom-context-2d-font>font</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current font settings.</p>

    <p>Can be set, to change the font. The syntax is the same as for the CSS <a id="text-styles:'font'" href=https://drafts.csswg.org/css-fonts/#font-prop data-x-internal="'font'">'font'</a>
    property; values that cannot be parsed as CSS font values are ignored. The default is "10px
    sans-serif".</p>

    <p>Relative keywords and lengths are computed relative to the font of the <code id=text-styles:the-canvas-element-3><a href=#the-canvas-element>canvas</a></code>
    element.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-textalign>textAlign</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-textalign id=text-styles:dom-context-2d-textalign>textAlign</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current text alignment settings.</p>

    <p>Can be set, to change the alignment. The possible values are and their meanings are given
    below. Other values are ignored. The default is "<code>start</code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-textbaseline>textBaseline</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-textbaseline id=text-styles:dom-context-2d-textbaseline>textBaseline</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current baseline alignment settings.</p>

    <p>Can be set, to change the baseline alignment. The possible values and their meanings are
    given below. Other values are ignored. The default is "<code id=text-styles:dom-context-2d-textbaseline-alphabetic><a href=#dom-context-2d-textbaseline-alphabetic>alphabetic</a></code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-direction>direction</span> [ = <var>value</var> ]</code><dt><code><var>styles</var>.<a href=#dom-context-2d-direction id=text-styles:dom-context-2d-direction>direction</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current directionality.</p>

    <p>Can be set, to change the directionality. The possible values and their meanings are given
    below. Other values are ignored. The default is "<code id=text-styles:dom-context-2d-direction-inherit><a href=#dom-context-2d-direction-inherit>inherit</a></code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-letterspacing>letterSpacing</span> [ = <var>value</var> ]</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in one engine only." class=less-than-two-engines-flag>⚠</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/letterSpacing title="The CanvasRenderingContext2D.letterSpacing property of the Canvas API specifies the spacing between letters when drawing text.">CanvasRenderingContext2D/letterSpacing</a><p class=less-than-two-engines-text>Support in one engine only.<div class=support><span class="firefox no"><span>Firefox</span><span>No</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>styles</var>.<a href=#dom-context-2d-letterspacing id=text-styles:dom-context-2d-letterspacing>letterSpacing</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current spacing between characters in the text.</p>

    <p>Can be set, to change spacing between characters. Values that cannot be parsed as a CSS
    <a id=text-styles:length-2 href=https://drafts.csswg.org/css-values/#lengths data-x-internal=length-2>&lt;length></a> are ignored. The default is "<code>0px</code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-fontkerning>fontKerning</span> [ = <var>value</var> ]</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fontKerning title="The CanvasRenderingContext2D.fontKerning property of the Canvas API specifies how font kerning information is used.">CanvasRenderingContext2D/fontKerning</a><div class=support><span class="firefox yes"><span>Firefox</span><span>104+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>styles</var>.<a href=#dom-context-2d-fontkerning id=text-styles:dom-context-2d-fontkerning>fontKerning</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current font kerning settings.</p>

    <p>Can be set, to change the font kerning. The possible values and their meanings are given
    below. Other values are ignored. The default is "<code id=text-styles:dom-context-2d-fontkerning-auto><a href=#dom-context-2d-fontkerning-auto>auto</a></code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-fontstretch>fontStretch</span> [ = <var>value</var> ]</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in one engine only." class=less-than-two-engines-flag>⚠</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fontStretch title="The CanvasRenderingContext2D.fontStretch property of the Canvas API specifies how the font may be expanded or condensed when drawing text.">CanvasRenderingContext2D/fontStretch</a><p class=less-than-two-engines-text>Support in one engine only.<div class=support><span class="firefox no"><span>Firefox</span><span>No</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>styles</var>.<a href=#dom-context-2d-fontstretch id=text-styles:dom-context-2d-fontstretch>fontStretch</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current font stretch settings.</p>

    <p>Can be set, to change the font stretch. The possible values and their meanings are given
    below. Other values are ignored. The default is "<code id=text-styles:dom-context-2d-fontstretch-normal><a href=#dom-context-2d-fontstretch-normal>normal</a></code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-fontvariantcaps>fontVariantCaps</span> [ = <var>value</var> ]</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in one engine only." class=less-than-two-engines-flag>⚠</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fontVariantCaps title="The CanvasRenderingContext2D.fontVariantCaps property of the Canvas API specifies an alternative capitalization of the rendered text.">CanvasRenderingContext2D/fontVariantCaps</a><p class=less-than-two-engines-text>Support in one engine only.<div class=support><span class="firefox no"><span>Firefox</span><span>No</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>styles</var>.<a href=#dom-context-2d-fontvariantcaps id=text-styles:dom-context-2d-fontvariantcaps>fontVariantCaps</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current font variant caps settings.</p>

    <p>Can be set, to change the font variant caps. The possible values and their meanings are given
    below. Other values are ignored. The default is "<code id=text-styles:dom-context-2d-fontvariantcaps-normal><a href=#dom-context-2d-fontvariantcaps-normal>normal</a></code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-textrendering>textRendering</span> [ = <var>value</var> ]</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in one engine only." class=less-than-two-engines-flag>⚠</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textRendering title="The CanvasRenderingContext2D.textRendering property of the Canvas API provides information to the rendering engine about what to optimize for when rendering text.">CanvasRenderingContext2D/textRendering</a><p class=less-than-two-engines-text>Support in one engine only.<div class=support><span class="firefox no"><span>Firefox</span><span>No</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>styles</var>.<a href=#dom-context-2d-textrendering id=text-styles:dom-context-2d-textrendering>textRendering</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current text rendering settings.</p>

    <p>Can be set, to change the text rendering. The possible values and their meanings are given
    below. Other values are ignored. The default is "<code id=text-styles:dom-context-2d-textrendering-auto><a href=#dom-context-2d-textrendering-auto>auto</a></code>".</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-wordspacing>wordSpacing</span> [ = <var>value</var> ]</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in one engine only." class=less-than-two-engines-flag>⚠</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/wordSpacing title="The CanvasRenderingContext2D.wordSpacing property of the Canvas API specifies the spacing between words when drawing text.">CanvasRenderingContext2D/wordSpacing</a><p class=less-than-two-engines-text>Support in one engine only.<div class=support><span class="firefox no"><span>Firefox</span><span>No</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>styles</var>.<a href=#dom-context-2d-wordspacing id=text-styles:dom-context-2d-wordspacing>wordSpacing</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current spacing between words in the text.</p>

    <p>Can be set, to change spacing between words. Values that cannot be parsed as a CSS
    <a id=text-styles:length-2-2 href=https://drafts.csswg.org/css-values/#lengths data-x-internal=length-2>&lt;length></a> are ignored. The default is "<code>0px</code>".</p>
   </dl>

  

  <p>The <code id=text-styles:dom-context-2d-textalign-2><a href=#dom-context-2d-textalign>textAlign</a></code> attribute's allowed keywords are
  as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasTextAlign id=dom-context-2d-textalign-start data-dfn-type=enum-value><code>start</code></dfn>
   <dd><p>Align to the start edge of the text (left side in left-to-right text, right side in
   right-to-left text).<dt><dfn data-dfn-for=CanvasTextAlign id=dom-context-2d-textalign-end data-dfn-type=enum-value><code>end</code></dfn>
   <dd><p>Align to the end edge of the text (right side in left-to-right text, left side in
   right-to-left text).<dt><dfn data-dfn-for=CanvasTextAlign id=dom-context-2d-textalign-left data-dfn-type=enum-value><code>left</code></dfn>
   <dd><p>Align to the left.<dt><dfn data-dfn-for=CanvasTextAlign id=dom-context-2d-textalign-right data-dfn-type=enum-value><code>right</code></dfn>
   <dd><p>Align to the right.<dt><dfn data-dfn-for=CanvasTextAlign id=dom-context-2d-textalign-center data-dfn-type=enum-value><code>center</code></dfn>
   <dd><p>Align to the center.</dl>

  <p>The <code id=text-styles:dom-context-2d-textbaseline-2><a href=#dom-context-2d-textbaseline>textBaseline</a></code>
  attribute's allowed keywords correspond to alignment points in the
  font:</p>

  <p><img alt="The em-over baseline is roughly at the top of the glyphs in a font, the hanging baseline is where some glyphs like आ are anchored, the middle is half-way between the em-over and em-under baselines, the alphabetic baseline is where characters like Á, ÿ, f, and Ω are anchored, the ideographic-under baseline is where glyphs like 私 and 達 are anchored, and the em-under baseline is roughly at the bottom of the glyphs in a font. The top and bottom of the bounding box can be far from these baselines, due to glyphs extending far outside em-over and em-under baselines." src=../images/baselines.png width=738 height=300></p>

  <p>The keywords map to these alignment points as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasTextBaseline id=dom-context-2d-textbaseline-top data-dfn-type=enum-value><code>top</code></dfn>
   <dd>The <a id=text-styles:em-over-baseline href=https://drafts.csswg.org/css-inline/#em-over-baseline data-x-internal=em-over-baseline>em-over baseline</a><dt><dfn data-dfn-for=CanvasTextBaseline id=dom-context-2d-textbaseline-hanging data-dfn-type=enum-value><code>hanging</code></dfn>
   <dd>The <a id=text-styles:hanging-baseline href=https://drafts.csswg.org/css-inline/#hanging-baseline data-x-internal=hanging-baseline>hanging baseline</a><dt><dfn data-dfn-for=CanvasTextBaseline id=dom-context-2d-textbaseline-middle data-dfn-type=enum-value><code>middle</code></dfn>
   <dd>Halfway between the <a id=text-styles:em-over-baseline-2 href=https://drafts.csswg.org/css-inline/#em-over-baseline data-x-internal=em-over-baseline>em-over baseline</a> and the <a id=text-styles:em-under-baseline href=https://drafts.csswg.org/css-inline/#em-under-baseline data-x-internal=em-under-baseline>em-under baseline</a><dt><dfn data-dfn-for=CanvasTextBaseline id=dom-context-2d-textbaseline-alphabetic data-dfn-type=enum-value><code>alphabetic</code></dfn>
   <dd>The <a id=text-styles:alphabetic-baseline href=https://drafts.csswg.org/css-inline/#alphabetic-baseline data-x-internal=alphabetic-baseline>alphabetic baseline</a><dt><dfn data-dfn-for=CanvasTextBaseline id=dom-context-2d-textbaseline-ideographic data-dfn-type=enum-value><code>ideographic</code></dfn>
   <dd>The <a id=text-styles:ideographic-under-baseline href=https://drafts.csswg.org/css-inline/#ideographic-under-baseline data-x-internal=ideographic-under-baseline>ideographic-under baseline</a><dt><dfn data-dfn-for=CanvasTextBaseline id=dom-context-2d-textbaseline-bottom data-dfn-type=enum-value><code>bottom</code></dfn>
   <dd>The <a id=text-styles:em-under-baseline-2 href=https://drafts.csswg.org/css-inline/#em-under-baseline data-x-internal=em-under-baseline>em-under baseline</a></dl>

  <p>The <code id=text-styles:dom-context-2d-direction-2><a href=#dom-context-2d-direction>direction</a></code> attribute's allowed keywords are
  as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasDirection id=dom-context-2d-direction-ltr data-dfn-type=enum-value><code>ltr</code></dfn>

   <dd><p>Treat input to the <a href=#text-preparation-algorithm id=text-styles:text-preparation-algorithm>text preparation algorithm</a> as left-to-right text.<dt><dfn data-dfn-for=CanvasDirection id=dom-context-2d-direction-rtl data-dfn-type=enum-value><code>rtl</code></dfn>

   <dd><p>Treat input to the <a href=#text-preparation-algorithm id=text-styles:text-preparation-algorithm-2>text preparation algorithm</a> as right-to-left text.<dt><dfn data-dfn-for=CanvasDirection id=dom-context-2d-direction-inherit data-dfn-type=enum-value><code>inherit</code></dfn>

   <dd><p>Use the process in the <a href=#text-preparation-algorithm id=text-styles:text-preparation-algorithm-3>text preparation algorithm</a> to obtain the text
   direction from the <code id=text-styles:the-canvas-element-4><a href=#the-canvas-element>canvas</a></code> element, <a href=#offscreencanvas-placeholder id=text-styles:offscreencanvas-placeholder>placeholder <code>canvas</code> element</a>, or
   <a id=text-styles:document-element-2 href=https://dom.spec.whatwg.org/#document-element data-x-internal=document-element>document element</a>.</dl>

  <p>The <code id=text-styles:dom-context-2d-fontkerning-2><a href=#dom-context-2d-fontkerning>fontKerning</a></code> attribute's allowed keywords
  are as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasFontKerning id=dom-context-2d-fontkerning-auto data-dfn-type=enum-value><code>auto</code></dfn>
   <dd><p>Kerning is applied at the discretion of the user agent.<dt><dfn data-dfn-for=CanvasFontKerning id=dom-context-2d-fontkerning-normal data-dfn-type=enum-value><code>normal</code></dfn>
   <dd><p>Kerning is applied.<dt><dfn data-dfn-for=CanvasFontKerning id=dom-context-2d-fontkerning-none data-dfn-type=enum-value><code>none</code></dfn>
   <dd><p>Kerning is not applied.</dl>

  <p>The <code id=text-styles:dom-context-2d-fontstretch-2><a href=#dom-context-2d-fontstretch>fontStretch</a></code> attribute's allowed keywords
  are as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-ultra-condensed data-dfn-type=enum-value><code>ultra-condensed</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'ultra-condensed'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-ultra-condensed data-x-internal="'ultra-condensed'">'ultra-condensed'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-extra-condensed data-dfn-type=enum-value><code>extra-condensed</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-2" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'extra-condensed'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-extra-condensed data-x-internal="'extra-condensed'">'extra-condensed'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-condensed data-dfn-type=enum-value><code>condensed</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-3" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'condensed'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-condensed data-x-internal="'condensed'">'condensed'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-semi-condensed data-dfn-type=enum-value><code>semi-condensed</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-4" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'semi-condensed'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-semi-condensed data-x-internal="'semi-condensed'">'semi-condensed'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-normal data-dfn-type=enum-value><code>normal</code></dfn>
   <dd><p>The default setting, where width of the glyphs is at 100%.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-semi-expanded data-dfn-type=enum-value><code>semi-expanded</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-5" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'semi-expanded'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-semi-expanded data-x-internal="'semi-expanded'">'semi-expanded'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-expanded data-dfn-type=enum-value><code>expanded</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-6" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'expanded'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-expanded data-x-internal="'expanded'">'expanded'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-extra-expanded data-dfn-type=enum-value><code>extra-expanded</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-7" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'extra-expanded'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-extra-expanded data-x-internal="'extra-expanded'">'extra-expanded'</a> setting.<dt><dfn data-dfn-for=CanvasFontStretch id=dom-context-2d-fontstretch-ultra-expanded data-dfn-type=enum-value><code>ultra-expanded</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-stretch'-8" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a> <a id="text-styles:'ultra-expanded'" href=https://drafts.csswg.org/css-fonts/#valdef-font-stretch-ultra-expanded data-x-internal="'ultra-expanded'">'ultra-expanded'</a> setting.</dl>

  <p>The <code id=text-styles:dom-context-2d-fontvariantcaps-2><a href=#dom-context-2d-fontvariantcaps>fontVariantCaps</a></code> attribute's allowed
  keywords are as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-normal data-dfn-type=enum-value><code>normal</code></dfn>
   <dd><p>None of the features listed below are enabled.<dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-small-caps data-dfn-type=enum-value><code>small-caps</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-variant-caps'" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a> <a id="text-styles:'small-caps'" href=https://drafts.csswg.org/css-fonts/#valdef-font-variant-caps-small-caps data-x-internal="'small-caps'">'small-caps'</a> setting.<dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-all-small-caps data-dfn-type=enum-value><code>all-small-caps</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-variant-caps'-2" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a> <a id="text-styles:'all-small-caps'" href=https://drafts.csswg.org/css-fonts/#valdef-font-variant-caps-all-small-caps data-x-internal="'all-small-caps'">'all-small-caps'</a> setting.<dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-petite-caps data-dfn-type=enum-value><code>petite-caps</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-variant-caps'-3" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a> <a id="text-styles:'petite-caps'" href=https://drafts.csswg.org/css-fonts/#valdef-font-variant-caps-petite-caps data-x-internal="'petite-caps'">'petite-caps'</a> setting.<dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-all-petite-caps data-dfn-type=enum-value><code>all-petite-caps</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-variant-caps'-4" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a> <a id="text-styles:'all-petite-caps'" href=https://drafts.csswg.org/css-fonts/#valdef-font-variant-caps-all-petite-caps data-x-internal="'all-petite-caps'">'all-petite-caps'</a> setting.<dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-unicase data-dfn-type=enum-value><code>unicase</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-variant-caps'-5" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a> <a id="text-styles:'unicase'" href=https://drafts.csswg.org/css-fonts/#valdef-font-variant-caps-unicase data-x-internal="'unicase'">'unicase'</a> setting.<dt><dfn data-dfn-for=CanvasFontVariantCaps id=dom-context-2d-fontvariantcaps-titling-caps data-dfn-type=enum-value><code>titling-caps</code></dfn>
   <dd><p>Same as CSS <a id="text-styles:'font-variant-caps'-6" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a> <a id="text-styles:'titling-caps'" href=https://drafts.csswg.org/css-fonts/#valdef-font-variant-caps-titling-caps data-x-internal="'titling-caps'">'titling-caps'</a> setting.</dl>

  <p>The <code id=text-styles:dom-context-2d-textrendering-2><a href=#dom-context-2d-textrendering>textRendering</a></code> attribute's allowed
  keywords are as follows:</p>

  <dl><dt><dfn data-dfn-for=CanvasTextRendering id=dom-context-2d-textrendering-auto data-dfn-type=enum-value><code>auto</code></dfn>
    <dd><p>Same as 'auto' in <a id=text-styles:svg-text-rendering href=https://svgwg.org/svg2-draft/painting.html#TextRendering data-x-internal=svg-text-rendering>SVG text-rendering</a> property.<dt><dfn data-dfn-for=CanvasTextRendering id=dom-context-2d-textrendering-optimizespeed data-dfn-type=enum-value><code>optimizeSpeed</code></dfn>
    <dd><p>Same as 'optimizeSpeed' in <a id=text-styles:svg-text-rendering-2 href=https://svgwg.org/svg2-draft/painting.html#TextRendering data-x-internal=svg-text-rendering>SVG text-rendering</a> property.<dt><dfn data-dfn-for=CanvasTextRendering id=dom-context-2d-textrendering-optimizelegibility data-dfn-type=enum-value><code>optimizeLegibility</code></dfn>
    <dd><p>Same as 'optimizeLegibility' in <a id=text-styles:svg-text-rendering-3 href=https://svgwg.org/svg2-draft/painting.html#TextRendering data-x-internal=svg-text-rendering>SVG text-rendering</a> property.<dt><dfn data-dfn-for=CanvasTextRendering id=dom-context-2d-textrendering-geometricprecision data-dfn-type=enum-value><code>geometricPrecision</code></dfn>
    <dd><p>Same as 'geometricPrecision' in <a id=text-styles:svg-text-rendering-4 href=https://svgwg.org/svg2-draft/painting.html#TextRendering data-x-internal=svg-text-rendering>SVG text-rendering</a> property.</dl>

  <p>The <dfn id=text-preparation-algorithm>text preparation algorithm</dfn> is as follows. It takes as input a string <var>text</var>,
  a <code>CanvasTextDrawingStyles</code> object <var>target</var>, and an optional length
  <var>maxWidth</var>. It returns an array of glyph shapes, each positioned on a common coordinate
  space, a <var>physical alignment</var> whose value is one of <i>left</i>, <i>right</i>, and
  <i>center</i>, and an <a id=text-styles:inline-box href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>. (Most callers of this algorithm ignore the
  <var>physical alignment</var> and the <a id=text-styles:inline-box-2 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>.)</p>

  <ol><li><p>If <var>maxWidth</var> was provided but is less than or equal to zero or equal to NaN,
   then return an empty array.<li><p>Replace all <a id=text-styles:space-characters href=https://infra.spec.whatwg.org/#ascii-whitespace data-x-internal=space-characters>ASCII whitespace</a> in <var>text</var> with U+0020 SPACE
   characters.<li><p>Let <var>font</var> be the current font of <var>target</var>, as given
   by that object's <code id=text-styles:dom-context-2d-font-2><a href=#dom-context-2d-font>font</a></code> attribute.<li><p>Let <var>language</var> be the <var>target</var>'s <span>language</span>.<li>
    <p>If <var>language</var> is "<code>inherit</code>":</p>

    <ol><li><p>Let <var>sourceObject</var> be <var>object</var>'s <span>font style source
     object</span>.<li><p>If <var>sourceObject</var> is a <code id=text-styles:the-canvas-element-5><a href=#the-canvas-element>canvas</a></code>
     element, then set <var>language</var> to the <var>sourceObject</var>'s
     <span>language</span>.<li>
      <p>Otherwise:</p>

      <ol><li><p><a id=text-styles:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>sourceObject</var> is an <code>OffscreenCanvas</code> object.<li><p>Set <var>language</var> to the <var>sourceObject</var>'s
       <span>inherited language</span>.</ol>
     </ol>
   <li><p>If <var>language</var> is the empty string, then set <var>language</var> to
   <span>explicitly unknown</span>.<li>
    <p>Apply the appropriate step from the following list to determine the value of
    <var>direction</var>:</p>

    <dl class=switch><dt>If the <var>target</var> object's <code id=text-styles:dom-context-2d-direction-3><a href=#dom-context-2d-direction>direction</a></code> attribute has the value "<code id=text-styles:dom-context-2d-direction-ltr><a href=#dom-context-2d-direction-ltr>ltr</a></code>"<dd>Let <var>direction</var> be '<a href=dom.html#concept-ltr id=text-styles:concept-ltr>ltr</a>'.<dt>If the <var>target</var> object's <code id=text-styles:dom-context-2d-direction-4><a href=#dom-context-2d-direction>direction</a></code> attribute has the value "<code id=text-styles:dom-context-2d-direction-rtl><a href=#dom-context-2d-direction-rtl>rtl</a></code>"<dd>Let <var>direction</var> be '<a href=dom.html#concept-rtl id=text-styles:concept-rtl>rtl</a>'.<dt>If the <var>target</var> object's <code id=text-styles:dom-context-2d-direction-5><a href=#dom-context-2d-direction>direction</a></code> attribute has the value "<code id=text-styles:dom-context-2d-direction-inherit-2><a href=#dom-context-2d-direction-inherit>inherit</a></code>"<dd>
      <ol><li><p>Let <var>sourceObject</var> be <var>object</var>'s <span>font style source
       object</span>.<li><p>If <var>sourceObject</var> is a <code id=text-styles:the-canvas-element-6><a href=#the-canvas-element>canvas</a></code>
       element, then let <var>direction</var> be <var>sourceObject</var>'s
       <a href=dom.html#the-directionality id=text-styles:the-directionality>directionality</a>.<li>
        <p>Otherwise:</p>
        <ol><li><p><a id=text-styles:assert-2 href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>sourceObject</var> is an <code>OffscreenCanvas</code> object.<li><p>Let <var>direction</var> be <var>sourceObject</var>'s
         <span>inherited direction</span>.</ol>
       </ol>
     </dl>
   <li>
    <p>Form a hypothetical infinitely-wide CSS <a id=text-styles:line-box href=https://drafts.csswg.org/css2/#line-box data-x-internal=line-box>line box</a> containing a single
    <a id=text-styles:inline-box-3 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a> containing the text <var>text</var>, with the CSS
    <a id=text-styles:content-language href=https://drafts.csswg.org/css-text-4/#content-language data-x-internal=content-language>content language</a> set to <var>language</var>, and with its CSS properties set as
    follows:</p>

    <table><thead><tr><th>Property<th>Source<tbody><tr><td><a id="text-styles:'direction'" href=https://drafts.csswg.org/css-writing-modes/#direction data-x-internal="'direction'">'direction'</a><td><var>direction</var><tr><td><a id="text-styles:'font'-2" href=https://drafts.csswg.org/css-fonts/#font-prop data-x-internal="'font'">'font'</a><td><var>font</var><tr><td><a id="text-styles:'font-kerning'" href=https://drafts.csswg.org/css-fonts/#propdef-font-kerning data-x-internal="'font-kerning'">'font-kerning'</a><td><var>target</var>'s <code id=text-styles:dom-context-2d-fontkerning-3><a href=#dom-context-2d-fontkerning>fontKerning</a></code><tr><td><a id="text-styles:'font-stretch'-9" href=https://drafts.csswg.org/css-fonts/#propdef-font-stretch data-x-internal="'font-stretch'">'font-stretch'</a><td><var>target</var>'s <code id=text-styles:dom-context-2d-fontstretch-3><a href=#dom-context-2d-fontstretch>fontStretch</a></code><tr><td><a id="text-styles:'font-variant-caps'-7" href=https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps data-x-internal="'font-variant-caps'">'font-variant-caps'</a><td><var>target</var>'s <code id=text-styles:dom-context-2d-fontvariantcaps-3><a href=#dom-context-2d-fontvariantcaps>fontVariantCaps</a></code><tr><td><a id="text-styles:'letter-spacing'" href=https://drafts.csswg.org/css-text/#letter-spacing-property data-x-internal="'letter-spacing'">'letter-spacing'</a><td><var>target</var>'s <span>letter spacing</span><tr><td><a id=text-styles:svg-text-rendering-5 href=https://svgwg.org/svg2-draft/painting.html#TextRendering data-x-internal=svg-text-rendering>SVG text-rendering</a><td><var>target</var>'s <code id=text-styles:dom-context-2d-textrendering-3><a href=#dom-context-2d-textrendering>textRendering</a></code><tr><td><a id="text-styles:'white-space'" href=https://drafts.csswg.org/css-text/#white-space-property data-x-internal="'white-space'">'white-space'</a><td>'pre'<tr><td><a id="text-styles:'word-spacing'" href=https://drafts.csswg.org/css-text/#propdef-word-spacing data-x-internal="'word-spacing'">'word-spacing'</a><td><var>target</var>'s <span>word spacing</span></table>

    <p>and with all other properties set to their initial values.</p>
   <li><p>If <var>maxWidth</var> was provided and the hypothetical width of the
   <a id=text-styles:inline-box-4 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a> in the hypothetical <a id=text-styles:line-box-2 href=https://drafts.csswg.org/css2/#line-box data-x-internal=line-box>line box</a> is greater than
   <var>maxWidth</var> <a href=https://drafts.csswg.org/css-values/#px id="text-styles:'px'" data-x-internal="'px'">CSS pixels</a>, then change <var>font</var> to have a
   more condensed font (if one is available or if a reasonably readable one can be synthesized by
   applying a horizontal scale factor to the font) or a smaller font, and return to the previous
   step.<li>
    <p>The <var>anchor point</var> is a point on the <a id=text-styles:inline-box-5 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, and the <var>physical
    alignment</var> is one of the values <i>left</i>, <i>right</i>, and <i>center</i>. These
    variables are determined by the <code id=text-styles:dom-context-2d-textalign-3><a href=#dom-context-2d-textalign>textAlign</a></code> and
    <code id=text-styles:dom-context-2d-textbaseline-3><a href=#dom-context-2d-textbaseline>textBaseline</a></code> values as follows:</p>

    <p>Horizontal position:</p>

    <dl><dt>If <code id=text-styles:dom-context-2d-textalign-4><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-left><a href=#dom-context-2d-textalign-left>left</a></code><dt>If <code id=text-styles:dom-context-2d-textalign-5><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-start><a href=#dom-context-2d-textalign-start>start</a></code> and <var>direction</var> is
     'ltr'<dt>If <code id=text-styles:dom-context-2d-textalign-6><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-end><a href=#dom-context-2d-textalign-end>end</a></code> and <var>direction</var> is 'rtl'<dd>Set the <var>anchor point</var>'s horizontal position to the left edge of the
     <a id=text-styles:inline-box-6 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, and let <var>physical alignment</var> be <i>left</i>.<dt>If <code id=text-styles:dom-context-2d-textalign-7><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-right><a href=#dom-context-2d-textalign-right>right</a></code><dt>If <code id=text-styles:dom-context-2d-textalign-8><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-end-2><a href=#dom-context-2d-textalign-end>end</a></code> and <var>direction</var> is 'ltr'<dt>If <code id=text-styles:dom-context-2d-textalign-9><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-start-2><a href=#dom-context-2d-textalign-start>start</a></code> and <var>direction</var> is
     'rtl'<dd>Set the <var>anchor point</var>'s horizontal position to the right edge of the
     <a id=text-styles:inline-box-7 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, and let <var>physical alignment</var> be <i>right</i>.<dt>If <code id=text-styles:dom-context-2d-textalign-10><a href=#dom-context-2d-textalign>textAlign</a></code> is <code id=text-styles:dom-context-2d-textalign-center><a href=#dom-context-2d-textalign-center>center</a></code><dd>Set the <var>anchor point</var>'s horizontal position to half way between the left
     and right edges of the <a id=text-styles:inline-box-8 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, and let <var>physical alignment</var> be
     <i>center</i>.</dl>

    <p>Vertical position:</p>

    <dl><dt>If <code id=text-styles:dom-context-2d-textbaseline-4><a href=#dom-context-2d-textbaseline>textBaseline</a></code> is <code id=text-styles:dom-context-2d-textbaseline-top><a href=#dom-context-2d-textbaseline-top>top</a></code><dd>Set the <var>anchor point</var>'s vertical position to the top of the em box of
     the <a id=text-styles:first-available-font href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a> of the <a id=text-styles:inline-box-9 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>.<dt>If <code id=text-styles:dom-context-2d-textbaseline-5><a href=#dom-context-2d-textbaseline>textBaseline</a></code> is <code id=text-styles:dom-context-2d-textbaseline-hanging><a href=#dom-context-2d-textbaseline-hanging>hanging</a></code><dd>Set the <var>anchor point</var>'s vertical position to the <a id=text-styles:hanging-baseline-2 href=https://drafts.csswg.org/css-inline/#hanging-baseline data-x-internal=hanging-baseline>hanging baseline</a> of
     the <a id=text-styles:first-available-font-2 href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a> of the <a id=text-styles:inline-box-10 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>.<dt>If <code id=text-styles:dom-context-2d-textbaseline-6><a href=#dom-context-2d-textbaseline>textBaseline</a></code> is <code id=text-styles:dom-context-2d-textbaseline-middle><a href=#dom-context-2d-textbaseline-middle>middle</a></code><dd>Set the <var>anchor point</var>'s vertical position to half way between the bottom
     and the top of the em box of the <a id=text-styles:first-available-font-3 href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a> of the <a id=text-styles:inline-box-11 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline
     box</a>.<dt>If <code id=text-styles:dom-context-2d-textbaseline-7><a href=#dom-context-2d-textbaseline>textBaseline</a></code> is <code id=text-styles:dom-context-2d-textbaseline-alphabetic-2><a href=#dom-context-2d-textbaseline-alphabetic>alphabetic</a></code><dd>Set the <var>anchor point</var>'s vertical position to the <a id=text-styles:alphabetic-baseline-2 href=https://drafts.csswg.org/css-inline/#alphabetic-baseline data-x-internal=alphabetic-baseline>alphabetic baseline</a>
     of the <a id=text-styles:first-available-font-4 href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a> of the <a id=text-styles:inline-box-12 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>.<dt>If <code id=text-styles:dom-context-2d-textbaseline-8><a href=#dom-context-2d-textbaseline>textBaseline</a></code> is <code id=text-styles:dom-context-2d-textbaseline-ideographic><a href=#dom-context-2d-textbaseline-ideographic>ideographic</a></code><dd>Set the <var>anchor point</var>'s vertical position to the <a id=text-styles:ideographic-under-baseline-2 href=https://drafts.csswg.org/css-inline/#ideographic-under-baseline data-x-internal=ideographic-under-baseline>ideographic-under
     baseline</a> of the <a id=text-styles:first-available-font-5 href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a> of the <a id=text-styles:inline-box-13 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>.<dt>If <code id=text-styles:dom-context-2d-textbaseline-9><a href=#dom-context-2d-textbaseline>textBaseline</a></code> is <code id=text-styles:dom-context-2d-textbaseline-bottom><a href=#dom-context-2d-textbaseline-bottom>bottom</a></code><dd>Set the <var>anchor point</var>'s vertical position to the bottom of the em box of
     the <a id=text-styles:first-available-font-6 href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a> of the <a id=text-styles:inline-box-14 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>.</dl>
   <li>
    <p>Let <var>result</var> be an array constructed by iterating over each glyph in the
    <a id=text-styles:inline-box-15 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a> from left to right (if any), adding to the array, for each glyph, the
    shape of the glyph as it is in the <a id=text-styles:inline-box-16 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, positioned on a coordinate space
    using <a href=https://drafts.csswg.org/css-values/#px id="text-styles:'px'-2" data-x-internal="'px'">CSS pixels</a> with its origin at the <var>anchor
    point</var>.</p>
   <li><p>Return <var>result</var>, <var>physical alignment</var>, and the inline
   box.</ol>


  <h6 id=building-paths><span class=secno>4.12.5.1.6</span> Building paths<a href=#building-paths class=self-link></a></h6>

  <p>Objects that implement the <code>CanvasPath</code> interface have a <a href=#concept-path id=building-paths:concept-path>path</a>. A <dfn id=concept-path>path</dfn> has a list of zero or
  more subpaths. Each subpath consists of a list of one or more points, connected by straight or
  curved <dfn id=line-segments>line segments</dfn>, and a flag indicating whether the subpath is closed or not. A
  closed subpath is one where the last point of the subpath is connected to the first point of the
  subpath by a straight line. Subpaths with only one point are ignored when painting the path.</p>

  <p><a href=#concept-path id=building-paths:concept-path-2>Paths</a> have a <dfn id=need-new-subpath>need new subpath</dfn> flag. When this
  flag is set, certain APIs create a new subpath rather than extending the previous one. When a
  <a href=#concept-path id=building-paths:concept-path-3>path</a> is created, its <a href=#need-new-subpath id=building-paths:need-new-subpath>need new subpath</a> flag must be
  set.</p>

  <p>When an object implementing the <code>CanvasPath</code> interface is created, its <a href=#concept-path id=building-paths:concept-path-4>path</a> must be initialized to zero subpaths.</p>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-moveto>moveTo</span>(<var>x</var>, <var>y</var>)</code><dt><code><var>path</var>.<a href=#dom-context-2d-moveto id=building-paths:dom-context-2d-moveto>moveTo</a>(<var>x</var>, <var>y</var>)</code><dd><p>Creates a new subpath with the given point.<dt><code><var>context</var>.<span id=dom-context-2d-closepath>closePath</span>()</code><dt><code><var>path</var>.<a href=#dom-context-2d-closepath id=building-paths:dom-context-2d-closepath>closePath</a>()</code><dd>
    <p>Marks the current subpath as closed, and starts a new subpath with a point the same as the
    start and end of the newly closed subpath.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-lineto>lineTo</span>(<var>x</var>, <var>y</var>)</code><dt><code><var>path</var>.<a href=#dom-context-2d-lineto id=building-paths:dom-context-2d-lineto>lineTo</a>(<var>x</var>, <var>y</var>)</code><dd>
    <p>Adds the given point to the current subpath, connected to the previous one by a straight
    line.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-quadraticcurveto>quadraticCurveTo</span>(<var>cpx</var>, <var>cpy</var>, <var>x</var>, <var>y</var>)</code><dt><code><var>path</var>.<a href=#dom-context-2d-quadraticcurveto id=building-paths:dom-context-2d-quadraticcurveto>quadraticCurveTo</a>(<var>cpx</var>, <var>cpy</var>, <var>x</var>, <var>y</var>)</code><dd>
    <p>Adds the given point to the current subpath, connected to the previous one by a quadratic
    Bézier curve with the given control point.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-beziercurveto>bezierCurveTo</span>(<var>cp1x</var>, <var>cp1y</var>, <var>cp2x</var>, <var>cp2y</var>, <var>x</var>, <var>y</var>)</code><dt><code><var>path</var>.<a href=#dom-context-2d-beziercurveto id=building-paths:dom-context-2d-beziercurveto>bezierCurveTo</a>(<var>cp1x</var>, <var>cp1y</var>, <var>cp2x</var>, <var>cp2y</var>, <var>x</var>, <var>y</var>)</code><dd>
    <p>Adds the given point to the current subpath, connected to the previous one by a cubic Bézier
    curve with the given control points.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-arcto>arcTo</span>(<var>x1</var>, <var>y1</var>, <var>x2</var>, <var>y2</var>, <var>radius</var>)</code><dt><code><var>path</var>.<a href=#dom-context-2d-arcto id=building-paths:dom-context-2d-arcto>arcTo</a>(<var>x1</var>, <var>y1</var>, <var>x2</var>, <var>y2</var>, <var>radius</var>)</code><dd>
    <p>Adds an arc with the given control points and radius to the current subpath, connected to the
    previous point by a straight line.</p>

    <p>Throws an <a id=building-paths:indexsizeerror href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a> <code id=building-paths:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if the given
    radius is negative.</p>

    <figure class=diagrams>
     
     <img alt="" src=../images/arcTo1.png width=357 height=254>
     <img alt="" src=../images/arcTo2.png width=468 height=310>
     <img alt="" src=../images/arcTo3.png width=513 height=233>
    </figure>


   <dt><code><var>context</var>.<span id=dom-context-2d-arc>arc</span>(<var>x</var>, <var>y</var>, <var>radius</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>counterclockwise</var> ])</code><dt><code><var>path</var>.<a href=#dom-context-2d-arc id=building-paths:dom-context-2d-arc>arc</a>(<var>x</var>, <var>y</var>, <var>radius</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>counterclockwise</var> ])</code><dd>
    <p>Adds points to the subpath such that the arc described by the circumference of the circle
    described by the arguments, starting at the given start angle and ending at the given end angle,
    going in the given direction (defaulting to clockwise), is added to the path, connected to the
    previous point by a straight line.</p>

    <p>Throws an <a id=building-paths:indexsizeerror-2 href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a> <code id=building-paths:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if the given
    radius is negative.</p>

    <figure class=diagrams>
     
     <img alt="" src=../images/arc1.png width=590 height=255>
    </figure>


   <dt><code><var>context</var>.<span id=dom-context-2d-ellipse>ellipse</span>(<var>x</var>, <var>y</var>, <var>radiusX</var>, <var>radiusY</var>, <var>rotation</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>counterclockwise</var>])</code><dt><code><var>path</var>.<a href=#dom-context-2d-ellipse id=building-paths:dom-context-2d-ellipse>ellipse</a>(<var>x</var>, <var>y</var>, <var>radiusX</var>, <var>radiusY</var>, <var>rotation</var>, <var>startAngle</var>, <var>endAngle</var> [, <var>counterclockwise</var>])</code><dd>
    <p>Adds points to the subpath such that the arc described by the circumference of the ellipse
    described by the arguments, starting at the given start angle and ending at the given end angle,
    going in the given direction (defaulting to clockwise), is added to the path, connected to the
    previous point by a straight line.</p>

    <p>Throws an <a id=building-paths:indexsizeerror-3 href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a> <code id=building-paths:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if the given
    radius is negative.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-rect>rect</span>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</code><dt><code><var>path</var>.<a href=#dom-context-2d-rect id=building-paths:dom-context-2d-rect>rect</a>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</code><dd><p>Adds a new closed subpath to the path, representing the given rectangle.<dt><code><var>context</var>.<span id=dom-context-2d-roundrect>roundRect</span>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>, <var>radii</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect title="The CanvasRenderingContext2D.roundRect() method of the Canvas 2D API adds a rounded rectangle to the current path.">CanvasRenderingContext2D/roundRect</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>112+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>99+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>99+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dt><code><var>path</var>.<a href=#dom-context-2d-roundrect id=building-paths:dom-context-2d-roundrect>roundRect</a>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>, <var>radii</var>)</code><dd>
    <p>Adds a new closed subpath to the path representing the given rounded rectangle.
    <var>radii</var> is either a list of radii or a single radius representing the corners of the
    rectangle in pixels. If a list is provided, the number and order of these radii function in the
    same way as the CSS <a id="building-paths:'border-radius'" href=https://drafts.csswg.org/css-backgrounds/#propdef-border-radius data-x-internal="'border-radius'">'border-radius'</a> property. A single radius behaves the same way
    as a list with a single element.</p>

    <p>If <var>w</var> and <var>h</var> are both greater than or equal to 0, or if both are smaller
    than 0, then the path is drawn clockwise. Otherwise, it is drawn counterclockwise.</p>

    <p>When <var>w</var> is negative, the rounded rectangle is flipped horizontally, which means
    that the radius values that normally apply to the left corners are used on the right and vice
    versa. Similarly, when <var>h</var> is negative, the rounded rect is flipped vertically.</p>

    <p>When a value <var>r</var> in <var>radii</var> is a number, the corresponding corner(s) are
    drawn as circular arcs of radius <var>r</var>.</p>

    <p>When a value <var>r</var> in <var>radii</var> is an object with <code>{ x, y
    }</code> properties, the corresponding corner(s) are drawn as elliptical arcs whose <var>x</var>
    and <var>y</var> radii are equal to <var>r.x</var> and <var>r.y</var>, respectively.</p>

    <p>When the sum of the <var>radii</var> of two corners of the same edge is greater than the
    length of the edge, all the <var>radii</var> of the rounded rectangle are scaled by a factor of
    length / (<var>r1</var> + <var>r2</var>). If multiple edges have this property, the scale factor
    of the edge with the smallest scale factor is used. This is consistent with CSS behavior.</p>

    <p>Throws a <code id=building-paths:js-rangeerror><a data-x-internal=js-rangeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-rangeerror>RangeError</a></code> if <var>radii</var> is a list whose
    size is not one, two, three, or four.</p>

    <p>Throws a <code id=building-paths:js-rangeerror-2><a data-x-internal=js-rangeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-rangeerror>RangeError</a></code> if a value in <var>radii</var> is a
    negative number, or is an <code>{ x, y }</code> object whose <code>x</code>
    or <code>y</code> properties are negative numbers.</p>

    
    
   </dl>

  



  <h6 id=path2d-objects><span class=secno>4.12.5.1.7</span> <code>Path2D</code> objects<a href=#path2d-objects class=self-link></a></h6><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Path2D title="The Path2D interface of the Canvas 2D API is used to declare a path that can then be used on a CanvasRenderingContext2D object. The path methods of the CanvasRenderingContext2D interface are also present on this interface, which gives you the convenience of being able to retain and replay your path whenever desired.">Path2D</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>31+</span></span><span class="safari yes"><span>Safari</span><span>8+</span></span><span class="chrome yes"><span>Chrome</span><span>36+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>14+</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  <p><code>Path2D</code> objects can be used to declare paths that are then later used on
  objects implementing the <code>CanvasDrawPath</code> interface. In addition to many of the APIs
  described in earlier sections, <code>Path2D</code> objects have methods to combine paths, and to
  add text to paths.</p>

  <dl class=domintro><dt><code><var>path</var> = new <span id=dom-path2d>Path2D</span>()</code><dd><p>Creates a new empty <code>Path2D</code> object.<dt><code><var>path</var> = new <a href=#dom-path2d id=path2d-objects:dom-path2d>Path2D</a>(<var>path</var>)</code><dd>
    <p>When <var>path</var> is a <code>Path2D</code> object, returns a copy.</p>

    <p>When <var>path</var> is a string, creates the path described by the argument, interpreted as
    SVG path data. <a href=references.html#refsSVG>[SVG]</a>
   <dt><code><var>path</var>.<span id=dom-path2d-addpath>addPath</span>(<var>path</var> [, <var>transform</var> ])</code><dd><p>Adds to the path the path given by the argument.</dl>

  


  <h6 id=transformations><span class=secno>4.12.5.1.8</span> <dfn>Transformations</dfn><a href=#transformations class=self-link></a></h6>

  <p>Objects that implement the <code>CanvasTransform</code> interface have a <dfn id=current-transformation-matrix>current
  transformation matrix</dfn>, as well as methods (described in this section) to manipulate it. When
  an object implementing the <code>CanvasTransform</code> interface is created, its transformation
  matrix must be initialized to the identity matrix.</p>

  <p>The <a href=#current-transformation-matrix id=transformations:current-transformation-matrix>current transformation matrix</a> is applied to coordinates when creating the
  <a href=#current-default-path id=transformations:current-default-path>current default path</a>, and when painting text, shapes, and <code>Path2D</code>
  objects, on objects implementing the <code>CanvasTransform</code> interface.</p>
  

  

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-scale>scale</span>(<var>x</var>, <var>y</var>)</code><dd>
    <p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-2>current transformation matrix</a> to apply a scaling transformation with
    the given characteristics.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-rotate>rotate</span>(<var>angle</var>)</code><dd>
    <p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-3>current transformation matrix</a> to apply a rotation transformation
    with the given characteristics. The angle is in radians.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-translate>translate</span>(<var>x</var>, <var>y</var>)</code><dd>
    <p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-4>current transformation matrix</a> to apply a translation transformation
    with the given characteristics.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-transform>transform</span>(<var>a</var>, <var>b</var>, <var>c</var>, <var>d</var>, <var>e</var>, <var>f</var>)</code><dd>
    <p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-5>current transformation matrix</a> to apply the matrix given by the
    arguments as described below.</p>
   <dt><code><var>matrix</var> = <var>context</var>.<span id=dom-context-2d-gettransform>getTransform</span>()</code><dd>
    <p>Returns a copy of the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-6>current transformation matrix</a>, as a newly created
    <code id=transformations:dommatrix><a data-x-internal=dommatrix href=https://drafts.fxtf.org/geometry/#dommatrix>DOMMatrix</a></code> object.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-settransform>setTransform</span>(<var>a</var>, <var>b</var>, <var>c</var>, <var>d</var>, <var>e</var>, <var>f</var>)</code><dd>
    <p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-7>current transformation matrix</a> <em>to</em> the matrix given by the
    arguments as described below.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-settransform-matrix>setTransform</span>(<var>transform</var>)</code><dd>
    <p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-8>current transformation matrix</a> <em>to</em> the matrix represented by
    the passed <code id=transformations:dommatrix2dinit><a data-x-internal=dommatrix2dinit href=https://drafts.fxtf.org/geometry/#dictdef-dommatrix2dinit>DOMMatrix2DInit</a></code> dictionary.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-resettransform>resetTransform</span>()</code><dd><p>Changes the <a href=#current-transformation-matrix id=transformations:current-transformation-matrix-9>current transformation matrix</a> to the identity matrix.</dl>

  

  <p class=note>The arguments <var>a</var>, <var>b</var>, <var>c</var>, <var>d</var>,
  <var>e</var>, and <var>f</var> are sometimes called <var>m11</var>, <var>m12</var>,
  <var>m21</var>, <var>m22</var>, <var>dx</var>, and <var>dy</var> or <var>m11</var>,
  <var>m21</var>, <var>m12</var>, <var>m22</var>, <var>dx</var>, and <var>dy</var>. Care ought to be
  taken in particular with the order of the second and third arguments (<var>b</var> and
  <var>c</var>) as their order varies from API to API and APIs sometimes use the notation
  <var>m12</var>/<var>m21</var> and sometimes <var>m21</var>/<var>m12</var> for those positions.</p>

  

  <div class=note>
   <p>Given a matrix of the form created by the <code id=transformations:dom-context-2d-transform><a href=#dom-context-2d-transform>transform()</a></code> and <code id=transformations:dom-context-2d-settransform><a href=#dom-context-2d-settransform>setTransform()</a></code> methods, i.e.,</p>

   <table class=matrix><tr><td><var>a</var><td><var>c</var><td><var>e</var><tr><td><var>b</var><td><var>d</var><td><var>f</var><tr><td>0<td>0<td>1</table>

   <p>the resulting transformed coordinates after transform matrix multiplication will be</p>

   <p class=equations>
    <var>x</var><sub>new</sub> = <var>a</var> <var>x</var> + <var>c</var> <var>y</var> + <var>e</var><br>
    <var>y</var><sub>new</sub> = <var>b</var> <var>x</var> + <var>d</var> <var>y</var> + <var>f</var>
   </p>
  </div>



  <h6 id=image-sources-for-2d-rendering-contexts><span class=secno>4.12.5.1.9</span> Image sources for 2D rendering contexts<a href=#image-sources-for-2d-rendering-contexts class=self-link></a></h6>

  <p>Some methods on the <code>CanvasDrawImage</code> and <code>CanvasFillStrokeStyles</code>
  interfaces take the union type <code>CanvasImageSource</code> as an argument.</p>

  <p>This union type allows objects implementing any of the following interfaces to be used as image
  sources:</p>

  <ul><li><code>HTMLOrSVGImageElement</code> (<code id=image-sources-for-2d-rendering-contexts:the-img-element><a href=embedded-content.html#the-img-element>img</a></code> or <a id=image-sources-for-2d-rendering-contexts:svg-image href=https://svgwg.org/svg2-draft/embedded.html#ImageElement data-x-internal=svg-image>SVG <code>image</code></a>
   elements)<li><code>HTMLVideoElement</code> (<code id=image-sources-for-2d-rendering-contexts:the-video-element><a href=media.html#the-video-element>video</a></code> elements)<li><code>HTMLCanvasElement</code> (<code id=image-sources-for-2d-rendering-contexts:the-canvas-element><a href=#the-canvas-element>canvas</a></code> elements)<li><code>OffscreenCanvas</code><li><code>ImageBitmap</code><li><code id=image-sources-for-2d-rendering-contexts:videoframe><a data-x-internal=videoframe href=https://w3c.github.io/webcodecs/#videoframe-interface>VideoFrame</a></code></ul>

  <p class=note>Although not formally specified as such, <a id=image-sources-for-2d-rendering-contexts:svg-image-2 href=https://svgwg.org/svg2-draft/embedded.html#ImageElement data-x-internal=svg-image>SVG <code>image</code></a>
  elements are expected to be implemented nearly identical to <code id=image-sources-for-2d-rendering-contexts:the-img-element-2><a href=embedded-content.html#the-img-element>img</a></code> elements. That is,
  <a id=image-sources-for-2d-rendering-contexts:svg-image-3 href=https://svgwg.org/svg2-draft/embedded.html#ImageElement data-x-internal=svg-image>SVG <code>image</code></a> elements share the fundamental concepts and features of
  <code id=image-sources-for-2d-rendering-contexts:the-img-element-3><a href=embedded-content.html#the-img-element>img</a></code> elements.</p>

  <p class=note>The <code>ImageBitmap</code> interface can be created from a number of other
  image-representing types, including <code>ImageData</code>.</p>

  <p>To <dfn id=check-the-usability-of-the-image-argument>check the usability of the <var>image</var> argument</dfn>, where <var>image</var>
  is a <code>CanvasImageSource</code> object, run these steps:</p>

  <ol><li>
    <p>Switch on <var>image</var>:</p>

    <dl class=switch><dt><code>HTMLOrSVGImageElement</code><dd>
      <p>If <var>image</var>'s <span>current request</span>'s <span>state</span> is <span>broken</span>, then
      throw an <a id=image-sources-for-2d-rendering-contexts:invalidstateerror href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a> <code id=image-sources-for-2d-rendering-contexts:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

      <p>If <var>image</var> is not <span>fully decodable</span>,
      then return <i>bad</i>.</p>

      <p>If <var>image</var> has a <a id=image-sources-for-2d-rendering-contexts:natural-width href=https://drafts.csswg.org/css-images/#natural-width data-x-internal=natural-width>natural width</a> or <a id=image-sources-for-2d-rendering-contexts:natural-height href=https://drafts.csswg.org/css-images/#natural-height data-x-internal=natural-height>natural height</a>
      (or both) equal to zero, then return <i>bad</i>.</p> 
     <dt><code>HTMLVideoElement</code><dd><p>If <var>image</var>'s <code id=image-sources-for-2d-rendering-contexts:dom-media-readystate><a href=media.html#dom-media-readystate>readyState</a></code>
     attribute is either <code id=image-sources-for-2d-rendering-contexts:dom-media-have_nothing><a href=media.html#dom-media-have_nothing>HAVE_NOTHING</a></code> or <code id=image-sources-for-2d-rendering-contexts:dom-media-have_metadata><a href=media.html#dom-media-have_metadata>HAVE_METADATA</a></code>, then return <i>bad</i>.<dt><code>HTMLCanvasElement</code><dt><code>OffscreenCanvas</code><dd><p>If <var>image</var> has either a horizontal dimension or a vertical dimension
     equal to zero, then throw an <a id=image-sources-for-2d-rendering-contexts:invalidstateerror-2 href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a>
     <code id=image-sources-for-2d-rendering-contexts:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<dt><code>ImageBitmap</code><dt><code id=image-sources-for-2d-rendering-contexts:videoframe-2><a data-x-internal=videoframe href=https://w3c.github.io/webcodecs/#videoframe-interface>VideoFrame</a></code><dd><p>If <var>image</var>'s <span>[[Detached]]</span> internal slot value
     is set to true, then throw an <a id=image-sources-for-2d-rendering-contexts:invalidstateerror-3 href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a>
     <code id=image-sources-for-2d-rendering-contexts:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</dl>
   <li>
    <p>Return <i>good</i>.</p>
   </ol>

  <p>When a <code>CanvasImageSource</code> object represents an <code>HTMLOrSVGImageElement</code>,
  the element's image must be used as the source image.</p>

  <p>Specifically, when a <code>CanvasImageSource</code> object represents an animated image in an
  <code>HTMLOrSVGImageElement</code>, the user agent must use the default image of the animation
  (the one that the format defines is to be used when animation is not supported or is disabled),
  or, if there is no such image, the first frame of the animation, when rendering the image for
  <code>CanvasRenderingContext2D</code> APIs.</p>

  <p>When a <code>CanvasImageSource</code> object represents an <code>HTMLVideoElement</code>, then
  the frame at the <span>current playback position</span> when the method with the argument is
  invoked must be used as the source image when rendering the image for
  <code>CanvasRenderingContext2D</code> APIs, and the source image's dimensions must be the <span>natural width</span> and <span>natural height</span> of the <a id=image-sources-for-2d-rendering-contexts:media-resource href=media.html#media-resource>media resource</a>
  (i.e., after any aspect-ratio correction has been applied).</p>

  <p>When a <code>CanvasImageSource</code> object represents an <code>HTMLCanvasElement</code>, the
  element's bitmap must be used as the source image.</p>

  <p>When a <code>CanvasImageSource</code> object represents an element that is <span>being
  rendered</span> and that element has been resized, the original image data of the source image
  must be used, not the image as it is rendered (e.g. <code id=image-sources-for-2d-rendering-contexts:attr-dim-width><a href=embedded-content-other.html#attr-dim-width>width</a></code> and
  <code id=image-sources-for-2d-rendering-contexts:attr-dim-height><a href=embedded-content-other.html#attr-dim-height>height</a></code> attributes on the source element have no effect on how
  the object is interpreted when rendering the image for <code>CanvasRenderingContext2D</code>
  APIs).</p>

  <p>When a <code>CanvasImageSource</code> object represents an <code>ImageBitmap</code>, the
  object's bitmap image data must be used as the source image.</p>

  <p>When a <code>CanvasImageSource</code> object represents an <code>OffscreenCanvas</code>, the
  object's bitmap must be used as the source image.</p>

  <p>When a <code>CanvasImageSource</code> object represents a <code id=image-sources-for-2d-rendering-contexts:videoframe-3><a data-x-internal=videoframe href=https://w3c.github.io/webcodecs/#videoframe-interface>VideoFrame</a></code>, the object's
  pixel data must be used as the source image, and the source image's dimensions must be the
  object's <a id=image-sources-for-2d-rendering-contexts:display-width href=https://w3c.github.io/webcodecs/#dom-videoframe-display-width-slot data-x-internal=display-width>[[display width]]</a> and <a id=image-sources-for-2d-rendering-contexts:display-height href=https://w3c.github.io/webcodecs/#dom-videoframe-display-height-slot data-x-internal=display-height>[[display height]]</a>.</p>

  <p>An object <var>image</var> <dfn id=the-image-argument-is-not-origin-clean>is not
  origin-clean</dfn> if, switching on <var>image</var>'s type:</p>

  <dl class=switch><dt><code>HTMLOrSVGImageElement</code>
   <dd><p><var>image</var>'s <span>current request</span>'s <span>image
   data</span> is <span>CORS-cross-origin</span>.<dt><code>HTMLVideoElement</code>
   <dd><p><var>image</var>'s <a id=image-sources-for-2d-rendering-contexts:media-data href=media.html#media-data>media data</a> is <span>CORS-cross-origin</span>.<dt><code>HTMLCanvasElement</code>
   <dt><code>ImageBitmap</code>
   <dt><code>OffscreenCanvas</code>
   <dd><p><var>image</var>'s bitmap's <span>origin-clean</span>
   flag is false.</dl>



  <h6 id=fill-and-stroke-styles><span class=secno>4.12.5.1.10</span> Fill and stroke styles<a href=#fill-and-stroke-styles class=self-link></a></h6>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-fillstyle>fillStyle</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current style used for filling shapes.</p>

    <p>Can be set, to change the <span>fill
    style</span>.</p>

    <p>The style can be either a string containing a CSS color, or a <code>CanvasGradient</code> or
    <code>CanvasPattern</code> object. Invalid values are ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-strokestyle>strokeStyle</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current style used for stroking shapes.</p>

    <p>Can be set, to change the <span>stroke
    style.</span></p>

    <p>The style can be either a string containing a CSS color, or a <code>CanvasGradient</code> or
    <code>CanvasPattern</code> object. Invalid values are ignored.</p>
   </dl>

  

  <hr>

  <p>There are three types of gradients, linear gradients, radial gradients, and conic gradients,
  represented by objects implementing the opaque <code>CanvasGradient</code> interface.</p>

  <p id=interpolation>Once a gradient has been created (see below), stops are placed along it to
  define how the colors are distributed along the gradient. </p>

  <dl class=domintro><dt><code><var>gradient</var>.<span id=dom-canvasgradient-addcolorstop>addColorStop</span>(<var>offset</var>, <var>color</var>)</code><dd>
    <p>Adds a color stop with the given color to the gradient at the given offset. 0.0 is the offset
    at one end of the gradient, 1.0 is the offset at the other end.</p>

    <p>Throws an <a id=fill-and-stroke-styles:indexsizeerror href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a> <code id=fill-and-stroke-styles:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if the offset
    is out of range. Throws a <a id=fill-and-stroke-styles:syntaxerror href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a> <code id=fill-and-stroke-styles:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if
    the color cannot be parsed.</p>
   <dt><code><var>gradient</var> = <var>context</var>.<span id=dom-context-2d-createlineargradient>createLinearGradient</span>(<var>x0</var>, <var>y0</var>, <var>x1</var>, <var>y1</var>)</code><dd>
    <p>Returns a <code>CanvasGradient</code> object that represents a linear gradient that paints
    along the line given by the coordinates represented by the arguments.</p>
   <dt><code><var>gradient</var> = <var>context</var>.<span id=dom-context-2d-createradialgradient>createRadialGradient</span>(<var>x0</var>, <var>y0</var>, <var>r0</var>, <var>x1</var>, <var>y1</var>, <var>r1</var>)</code><dd>
    <p>Returns a <code>CanvasGradient</code> object that represents a radial gradient that paints
    along the cone given by the circles represented by the arguments.</p>

    <p>If either of the radii are negative, throws an <a id=fill-and-stroke-styles:indexsizeerror-2 href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a>
    <code id=fill-and-stroke-styles:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>
   <dt><code><var>gradient</var> = <var>context</var>.<span id=dom-context-2d-createconicgradient>createConicGradient</span>(<var>startAngle</var>, <var>x</var>, <var>y</var>)</code><dd><p>Returns a <code>CanvasGradient</code> object that represents a conic gradient that paints
   clockwise along the rotation around the center represented by the arguments.</dl>

  

  <hr>

  <p>Patterns are represented by objects implementing the opaque <code>CanvasPattern</code>
  interface.</p>

  <dl class=domintro><dt><code><var>pattern</var> = <var>context</var>.<span id=dom-context-2d-createpattern>createPattern</span>(<var>image</var>, <var>repetition</var>)</code><dd>
    <p>Returns a <code>CanvasPattern</code> object that uses the given image and repeats in the
    direction(s) given by the <var>repetition</var> argument.</p>

    <p>The allowed values for <var>repetition</var> are <code>repeat</code> (both
    directions), <code>repeat-x</code> (horizontal only), <code>repeat-y</code>
    (vertical only), and <code>no-repeat</code> (neither). If the <var>repetition</var>
    argument is empty, the value <code>repeat</code> is used.</p>

    <p>If the image isn't yet fully decoded, then nothing is drawn. If the image is a canvas with no
    data, throws an <a id=fill-and-stroke-styles:invalidstateerror href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a> <code id=fill-and-stroke-styles:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>
   <dt><code><var>pattern</var>.<span id=dom-canvaspattern-settransform>setTransform</span>(<var>transform</var>)</code><dd>
    <p>Sets the transformation matrix that will be used when rendering the pattern during a fill or
    stroke painting operation.</p>
   </dl>

  




  <h6 id=drawing-rectangles-to-the-bitmap><span class=secno>4.12.5.1.11</span> Drawing rectangles to the bitmap<a href=#drawing-rectangles-to-the-bitmap class=self-link></a></h6>

  <p>Objects that implement the <code>CanvasRect</code> interface provide the following methods for
  immediately drawing rectangles to the bitmap. The methods each take four arguments; the first two
  give the <var>x</var> and <var>y</var> coordinates of the top left of the rectangle, and the
  second two give the width <var>w</var> and height <var>h</var> of the rectangle, respectively.</p>

  

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-clearrect>clearRect</span>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</code><dd><p>Clears all pixels on the bitmap in the given rectangle to <a id=drawing-rectangles-to-the-bitmap:transparent-black href=https://drafts.csswg.org/css-color/#transparent-black data-x-internal=transparent-black>transparent
   black</a>.<dt><code><var>context</var>.<span id=dom-context-2d-fillrect>fillRect</span>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</code><dd><p>Paints the given rectangle onto the bitmap, using the current fill style.<dt><code><var>context</var>.<span id=dom-context-2d-strokerect>strokeRect</span>(<var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</code><dd>
    <p>Paints the box that outlines the given rectangle onto the bitmap, using the current stroke
    style.</p>
   </dl>

  



  <h6 id=drawing-text-to-the-bitmap><span class=secno>4.12.5.1.12</span> Drawing text to the bitmap<a href=#drawing-text-to-the-bitmap class=self-link></a></h6><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D title="The CanvasRenderingContext2D interface, part of the Canvas API, provides the 2D rendering context for the drawing surface of a <canvas> element. It is used for drawing shapes, text, images, and other objects.">CanvasRenderingContext2D</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>1.5+</span></span><span class="safari yes"><span>Safari</span><span>2+</span></span><span class="chrome yes"><span>Chrome</span><span>1+</span></span><hr><span class="opera yes"><span>Opera</span><span>9+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>9+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>10.1+</span></span></div></div></div>

  <dl id=text-0 class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-filltext>fillText</span>(<var>text</var>, <var>x</var>, <var>y</var> [, <var>maxWidth</var> ])</code><dt><code><var>context</var>.<span id=dom-context-2d-stroketext>strokeText</span>(<var>text</var>, <var>x</var>, <var>y</var> [, <var>maxWidth</var> ])</code><dd>
    <p>Fills or strokes (respectively) the given text at the given position. If a maximum width is
    provided, the text will be scaled to fit that width if necessary.</p>
   <dt><code><var>metrics</var> = <var>context</var>.<span id=dom-context-2d-measuretext>measureText</span>(<var>text</var>)</code><dd>
    <p>Returns a <code>TextMetrics</code> object with the metrics of the given text in the current
    font.</p>
   <dt><code><var>metrics</var>.<a href=#dom-textmetrics-width-2 id=dom-textmetrics-width>width</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-actualboundingboxleft-2 id=dom-textmetrics-actualboundingboxleft>actualBoundingBoxLeft</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-actualboundingboxright-2 id=dom-textmetrics-actualboundingboxright>actualBoundingBoxRight</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-fontboundingboxascent-2 id=dom-textmetrics-fontboundingboxascent>fontBoundingBoxAscent</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-fontboundingboxdescent-2 id=dom-textmetrics-fontboundingboxdescent>fontBoundingBoxDescent</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-actualboundingboxascent-2 id=dom-textmetrics-actualboundingboxascent>actualBoundingBoxAscent</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-actualboundingboxdescent-2 id=dom-textmetrics-actualboundingboxdescent>actualBoundingBoxDescent</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-emheightascent-2 id=dom-textmetrics-emheightascent>emHeightAscent</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-emheightdescent-2 id=dom-textmetrics-emheightdescent>emHeightDescent</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-hangingbaseline-2 id=dom-textmetrics-hangingbaseline>hangingBaseline</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-alphabeticbaseline-2 id=dom-textmetrics-alphabeticbaseline>alphabeticBaseline</a></code><dt><code><var>metrics</var>.<a href=#dom-textmetrics-ideographicbaseline-2 id=dom-textmetrics-ideographicbaseline>ideographicBaseline</a></code><dd><p>Returns the measurement described below.</dl>

  

  <dl><dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-width-2 data-dfn-type=attribute><code>width</code></dfn>
   attribute<dd><p>The width of that <a id=drawing-text-to-the-bitmap:inline-box href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'" data-x-internal="'px'">CSS pixels</a>. (The
   text's advance width.)<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-actualboundingboxleft-2 data-dfn-type=attribute><code>actualBoundingBoxLeft</code></dfn> attribute<dd>
    <p>The distance parallel to the baseline from the alignment point given by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textalign><a href=#dom-context-2d-textalign>textAlign</a></code> attribute to the left side of the bounding
    rectangle of the given text, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-2" data-x-internal="'px'">CSS pixels</a>; positive numbers
    indicating a distance going left from the given alignment point.

    <p class=note>The sum of this value and the next (<code id=drawing-text-to-the-bitmap:dom-textmetrics-actualboundingboxright-2><a href=#dom-textmetrics-actualboundingboxright-2>actualBoundingBoxRight</a></code>) can be wider than
    the width of the <a id=drawing-text-to-the-bitmap:inline-box-2 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a> (<code id=drawing-text-to-the-bitmap:dom-textmetrics-width-2><a href=#dom-textmetrics-width-2>width</a></code>), in
    particular with slanted fonts where characters overhang their advance width.</p>
   <dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-actualboundingboxright-2 data-dfn-type=attribute><code>actualBoundingBoxRight</code></dfn> attribute<dd>
    <p>The distance parallel to the baseline from the alignment point given by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textalign-2><a href=#dom-context-2d-textalign>textAlign</a></code> attribute to the right side of the bounding
    rectangle of the given text, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-3" data-x-internal="'px'">CSS pixels</a>; positive numbers
    indicating a distance going right from the given alignment point.</p>
   <dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-fontboundingboxascent-2 data-dfn-type=attribute><code>fontBoundingBoxAscent</code></dfn> attribute<dd>
    <p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:ascent-metric href=https://drafts.csswg.org/css-inline/#ascent-metric data-x-internal=ascent-metric>ascent
    metric</a> of the <a id=drawing-text-to-the-bitmap:first-available-font href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-4" data-x-internal="'px'">CSS
    pixels</a>; positive numbers indicating a distance going up from the given baseline.</p>

    <p class=note>This value and the next are useful when rendering a background that have to have
    a consistent height even if the exact text being rendered changes. The <code id=drawing-text-to-the-bitmap:dom-textmetrics-actualboundingboxascent-2><a href=#dom-textmetrics-actualboundingboxascent-2>actualBoundingBoxAscent</a></code> attribute (and
    its corresponding attribute for the descent) are useful when drawing a bounding box around
    specific text.</p>
   <dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-fontboundingboxdescent-2 data-dfn-type=attribute><code>fontBoundingBoxDescent</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-2><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:descent-metric href=https://drafts.csswg.org/css-inline/#descent-metric data-x-internal=descent-metric>descent
   metric</a> of the <a id=drawing-text-to-the-bitmap:first-available-font-2 href=https://drafts.csswg.org/css-fonts/#first-available-font data-x-internal=first-available-font>first available font</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-5" data-x-internal="'px'">CSS pixels</a>;
   positive numbers indicating a distance going down from the given baseline.<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-actualboundingboxascent-2 data-dfn-type=attribute><code>actualBoundingBoxAscent</code></dfn> attribute<dd>
    <p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-3><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the top of the bounding
    rectangle of the given text, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-6" data-x-internal="'px'">CSS pixels</a>; positive numbers
    indicating a distance going up from the given baseline.

    <p class=note>This number can vary greatly based on the input text, even if the first font
    specified covers all the characters in the input. For example, the <code id=drawing-text-to-the-bitmap:dom-textmetrics-actualboundingboxascent-2-2><a href=#dom-textmetrics-actualboundingboxascent-2>actualBoundingBoxAscent</a></code> of a lowercase
    "o" from an <a id=drawing-text-to-the-bitmap:alphabetic-baseline href=https://drafts.csswg.org/css-inline/#alphabetic-baseline data-x-internal=alphabetic-baseline>alphabetic baseline</a> would be less than that of an uppercase "F". The
    value can easily be negative; for example, the distance from the top of the em box (<code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-4><a href=#dom-context-2d-textbaseline>textBaseline</a></code> value "<code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-top><a href=#dom-context-2d-textbaseline-top>top</a></code>") to the top of the bounding rectangle when
    the given text is just a single comma "<code>,</code>" would likely (unless the font is
    quite unusual) be negative.</p>
   <dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-actualboundingboxdescent-2 data-dfn-type=attribute><code>actualBoundingBoxDescent</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-5><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the bottom of the bounding
   rectangle of the given text, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-7" data-x-internal="'px'">CSS pixels</a>; positive numbers
   indicating a distance going down from the given baseline.<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-emheightascent-2 data-dfn-type=attribute><code>emHeightAscent</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-6><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:em-over-baseline href=https://drafts.csswg.org/css-inline/#em-over-baseline data-x-internal=em-over-baseline>em-over
   baseline</a> in the <a id=drawing-text-to-the-bitmap:inline-box-3 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-8" data-x-internal="'px'">CSS pixels</a>;
   positive numbers indicating that the given baseline is below the <a id=drawing-text-to-the-bitmap:em-over-baseline-2 href=https://drafts.csswg.org/css-inline/#em-over-baseline data-x-internal=em-over-baseline>em-over baseline</a>
   (so this value will usually be positive). Zero if the given baseline is the <a id=drawing-text-to-the-bitmap:em-over-baseline-3 href=https://drafts.csswg.org/css-inline/#em-over-baseline data-x-internal=em-over-baseline>em-over
   baseline</a>; half the font size if the given baseline is halfway between the <a id=drawing-text-to-the-bitmap:em-over-baseline-4 href=https://drafts.csswg.org/css-inline/#em-over-baseline data-x-internal=em-over-baseline>em-over
   baseline</a> and the <a id=drawing-text-to-the-bitmap:em-under-baseline href=https://drafts.csswg.org/css-inline/#em-under-baseline data-x-internal=em-under-baseline>em-under baseline</a>.<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-emheightdescent-2 data-dfn-type=attribute><code>emHeightDescent</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-7><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:em-under-baseline-2 href=https://drafts.csswg.org/css-inline/#em-under-baseline data-x-internal=em-under-baseline>em-under
   baseline</a> in the <a id=drawing-text-to-the-bitmap:inline-box-4 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-9" data-x-internal="'px'">CSS pixels</a>;
   positive numbers indicating that the given baseline is above the <a id=drawing-text-to-the-bitmap:em-under-baseline-3 href=https://drafts.csswg.org/css-inline/#em-under-baseline data-x-internal=em-under-baseline>em-under baseline</a>.
   (Zero if the given baseline is the <a id=drawing-text-to-the-bitmap:em-under-baseline-4 href=https://drafts.csswg.org/css-inline/#em-under-baseline data-x-internal=em-under-baseline>em-under baseline</a>.)<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-hangingbaseline-2 data-dfn-type=attribute><code>hangingBaseline</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-8><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:hanging-baseline href=https://drafts.csswg.org/css-inline/#hanging-baseline data-x-internal=hanging-baseline>hanging
   baseline</a> of the <a id=drawing-text-to-the-bitmap:inline-box-5 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-10" data-x-internal="'px'">CSS pixels</a>;
   positive numbers indicating that the given baseline is below the <a id=drawing-text-to-the-bitmap:hanging-baseline-2 href=https://drafts.csswg.org/css-inline/#hanging-baseline data-x-internal=hanging-baseline>hanging baseline</a>.
   (Zero if the given baseline is the <a id=drawing-text-to-the-bitmap:hanging-baseline-3 href=https://drafts.csswg.org/css-inline/#hanging-baseline data-x-internal=hanging-baseline>hanging baseline</a>.)<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-alphabeticbaseline-2 data-dfn-type=attribute><code>alphabeticBaseline</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-9><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:alphabetic-baseline-2 href=https://drafts.csswg.org/css-inline/#alphabetic-baseline data-x-internal=alphabetic-baseline>alphabetic
   baseline</a> of the <a id=drawing-text-to-the-bitmap:inline-box-6 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-11" data-x-internal="'px'">CSS pixels</a>;
   positive numbers indicating that the given baseline is below the <a id=drawing-text-to-the-bitmap:alphabetic-baseline-3 href=https://drafts.csswg.org/css-inline/#alphabetic-baseline data-x-internal=alphabetic-baseline>alphabetic
   baseline</a>. (Zero if the given baseline is the <a id=drawing-text-to-the-bitmap:alphabetic-baseline-4 href=https://drafts.csswg.org/css-inline/#alphabetic-baseline data-x-internal=alphabetic-baseline>alphabetic baseline</a>.)<dt><dfn data-dfn-for=TextMetrics id=dom-textmetrics-ideographicbaseline-2 data-dfn-type=attribute><code>ideographicBaseline</code></dfn> attribute<dd><p>The distance from the horizontal line indicated by the <code id=drawing-text-to-the-bitmap:dom-context-2d-textbaseline-10><a href=#dom-context-2d-textbaseline>textBaseline</a></code> attribute to the <a id=drawing-text-to-the-bitmap:ideographic-under-baseline href=https://drafts.csswg.org/css-inline/#ideographic-under-baseline data-x-internal=ideographic-under-baseline>ideographic-under
   baseline</a> of the <a id=drawing-text-to-the-bitmap:inline-box-7 href=https://drafts.csswg.org/css2/#inline-box data-x-internal=inline-box>inline box</a>, in <a href=https://drafts.csswg.org/css-values/#px id="drawing-text-to-the-bitmap:'px'-12" data-x-internal="'px'">CSS pixels</a>;
   positive numbers indicating that the given baseline is below the <a id=drawing-text-to-the-bitmap:ideographic-under-baseline-2 href=https://drafts.csswg.org/css-inline/#ideographic-under-baseline data-x-internal=ideographic-under-baseline>ideographic-under
   baseline</a>. (Zero if the given baseline is the <a id=drawing-text-to-the-bitmap:ideographic-under-baseline-3 href=https://drafts.csswg.org/css-inline/#ideographic-under-baseline data-x-internal=ideographic-under-baseline>ideographic-under
   baseline</a>.)</dl>

  <p class=note>Glyphs rendered using <code id=drawing-text-to-the-bitmap:dom-context-2d-filltext><a href=#dom-context-2d-filltext>fillText()</a></code> and
  <code id=drawing-text-to-the-bitmap:dom-context-2d-stroketext><a href=#dom-context-2d-stroketext>strokeText()</a></code> can spill out of the box given by the
  font size and the width returned by <code id=drawing-text-to-the-bitmap:dom-context-2d-measuretext><a href=#dom-context-2d-measuretext>measureText()</a></code>
  (the text width). Authors are encouraged to use the bounding box values described above if this is
  an issue.</p>

  <p class=note>A future version of the 2D context API might provide a way to render fragments of
  documents, rendered using CSS, straight to the canvas. This would be provided in preference to a
  dedicated way of doing multiline layout.</p>



  <h6 id=drawing-paths-to-the-canvas><span class=secno>4.12.5.1.13</span> Drawing paths to the canvas<a href=#drawing-paths-to-the-canvas class=self-link></a></h6>

  <p>Objects that implement the <code>CanvasDrawPath</code> interface have a <dfn id=current-default-path>current default
  path</dfn>. There is only one <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path>current default path</a>, it is not part of the
  <a href=#drawing-state id=drawing-paths-to-the-canvas:drawing-state>drawing state</a>. The <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-2>current default path</a> is a <a href=#concept-path id=drawing-paths-to-the-canvas:concept-path>path</a>, as described above.</p>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-beginpath>beginPath</span>()</code><dd><p>Resets the <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-3>current default path</a>.<dt><code><var>context</var>.<span id=dom-context-2d-fill>fill</span>([ <var>fillRule</var> ])</code><dt><code><var>context</var>.<a href=#dom-context-2d-fill id=drawing-paths-to-the-canvas:dom-context-2d-fill>fill</a>(<var>path</var> [, <var>fillRule</var> ])</code><dd>
    <p>Fills the subpaths of the <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-4>current default path</a> or the given path with the
    current fill style, obeying the given fill rule.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-stroke>stroke</span>()</code><dt><code><var>context</var>.<a href=#dom-context-2d-stroke id=drawing-paths-to-the-canvas:dom-context-2d-stroke>stroke</a>(<var>path</var>)</code><dd>
    <p>Strokes the subpaths of the <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-5>current default path</a> or the given path with the
    current stroke style.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-clip>clip</span>([ <var>fillRule</var> ])</code><dt><code><var>context</var>.<a href=#dom-context-2d-clip id=drawing-paths-to-the-canvas:dom-context-2d-clip>clip</a>(<var>path</var> [, <var>fillRule</var> ])</code><dd>
    <p>Further constrains the clipping region to the <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-6>current default path</a> or the given
    path, using the given fill rule to determine what points are in the path.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-ispointinpath>isPointInPath</span>(<var>x</var>, <var>y</var> [, <var>fillRule</var> ])</code><dt><code><var>context</var>.<a href=#dom-context-2d-ispointinpath id=drawing-paths-to-the-canvas:dom-context-2d-ispointinpath>isPointInPath</a>(<var>path</var>, <var>x</var>, <var>y</var> [, <var>fillRule</var> ])</code><dd>
    <p>Returns true if the given point is in the <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-7>current default path</a> or the given
    path, using the given fill rule to determine what points are in the path.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-ispointinstroke>isPointInStroke</span>(<var>x</var>, <var>y</var>)</code><dt><code><var>context</var>.<a href=#dom-context-2d-ispointinstroke id=drawing-paths-to-the-canvas:dom-context-2d-ispointinstroke>isPointInStroke</a>(<var>path</var>, <var>x</var>, <var>y</var>)</code><dd>
    <p>Returns true if the given point would be in the region covered by the stroke of the
    <a href=#current-default-path id=drawing-paths-to-the-canvas:current-default-path-8>current default path</a> or the given path, given the current stroke style.</p>
   </dl>

  

  <div id=drawCustomFocusRingExample class=example><a href=#drawCustomFocusRingExample class=self-link></a>

   <p>This <code id=drawing-paths-to-the-canvas:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element has a couple of checkboxes. The path-related commands are
   highlighted:</p>

   <pre><code class='html'><c- p>&lt;</c-><c- f>canvas</c-> <c- e>height</c-><c- o>=</c-><c- s>400</c-> <c- e>width</c-><c- o>=</c-><c- s>750</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>label</c-><c- p>&gt;&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>checkbox</c-> <c- e>id</c-><c- o>=</c-><c- s>showA</c-><c- p>&gt;</c-> Show As<c- p>&lt;/</c-><c- f>label</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>label</c-><c- p>&gt;&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>checkbox</c-> <c- e>id</c-><c- o>=</c-><c- s>showB</c-><c- p>&gt;</c-> Show Bs<c- p>&lt;/</c-><c- f>label</c-><c- p>&gt;</c->
 <c- c>&lt;!-- ... --&gt;</c->
<c- p>&lt;/</c-><c- f>canvas</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
 <c- a>function</c-> drawCheckbox<c- p>(</c->context<c- p>,</c-> element<c- p>,</c-> x<c- p>,</c-> y<c- p>,</c-> paint<c- p>)</c-> <c- p>{</c->
   context<c- p>.</c->save<c- p>();</c->
   context<c- p>.</c->font <c- o>=</c-> <c- t>&apos;10px sans-serif&apos;</c-><c- p>;</c->
   context<c- p>.</c->textAlign <c- o>=</c-> <c- t>&apos;left&apos;</c-><c- p>;</c->
   context<c- p>.</c->textBaseline <c- o>=</c-> <c- t>&apos;middle&apos;</c-><c- p>;</c->
   <c- a>var</c-> metrics <c- o>=</c-> context<c- p>.</c->measureText<c- p>(</c->element<c- p>.</c->labels<c- p>[</c-><c- mf>0</c-><c- p>].</c->textContent<c- p>);</c->
   <c- k>if</c-> <c- p>(</c->paint<c- p>)</c-> <c- p>{</c->
<strong>     context<c- p>.</c->beginPath<c- p>();</c->
     context<c- p>.</c->strokeStyle <c- o>=</c-> <c- t>&apos;black&apos;</c-><c- p>;</c->
     context<c- p>.</c->rect<c- p>(</c->x<c- o>-</c-><c- mf>5</c-><c- p>,</c-> y<c- o>-</c-><c- mf>5</c-><c- p>,</c-> <c- mf>10</c-><c- p>,</c-> <c- mf>10</c-><c- p>);</c->
     context<c- p>.</c->stroke<c- p>();</c->
</strong>     <c- k>if</c-> <c- p>(</c->element<c- p>.</c->checked<c- p>)</c-> <c- p>{</c->
<strong>       context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;black&apos;</c-><c- p>;</c->
       context<c- p>.</c->fill<c- p>();</c->
</strong>     <c- p>}</c->
     context<c- p>.</c->fillText<c- p>(</c->element<c- p>.</c->labels<c- p>[</c-><c- mf>0</c-><c- p>].</c->textContent<c- p>,</c-> x<c- o>+</c-><c- mf>5</c-><c- p>,</c-> y<c- p>);</c->
   <c- p>}</c->
<strong>   context<c- p>.</c->beginPath<c- p>();</c->
   context<c- p>.</c->rect<c- p>(</c->x<c- o>-</c-><c- mf>7</c-><c- p>,</c-> y<c- o>-</c-><c- mf>7</c-><c- p>,</c-> <c- mf>12</c-> <c- o>+</c-> metrics<c- p>.</c->width<c- o>+</c-><c- mf>2</c-><c- p>,</c-> <c- mf>14</c-><c- p>);</c->
</strong>
   context<c- p>.</c->drawFocusIfNeeded<c- p>(</c->element<c- p>);</c->
   context<c- p>.</c->restore<c- p>();</c->
 <c- p>}</c->
 <c- a>function</c-> drawBase<c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-> <c- p>}</c->
 <c- a>function</c-> drawAs<c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-> <c- p>}</c->
 <c- a>function</c-> drawBs<c- p>()</c-> <c- p>{</c-> <c- d>/* ... */</c-> <c- p>}</c->
 <c- a>function</c-> redraw<c- p>()</c-> <c- p>{</c->
   <c- a>var</c-> canvas <c- o>=</c-> document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
   <c- a>var</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->
   context<c- p>.</c->clearRect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->
   drawCheckbox<c- p>(</c->context<c- p>,</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showA&apos;</c-><c- p>),</c-> <c- mf>20</c-><c- p>,</c-> <c- mf>40</c-><c- p>,</c-> <c- kc>true</c-><c- p>);</c->
   drawCheckbox<c- p>(</c->context<c- p>,</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showB&apos;</c-><c- p>),</c-> <c- mf>20</c-><c- p>,</c-> <c- mf>60</c-><c- p>,</c-> <c- kc>true</c-><c- p>);</c->
   drawBase<c- p>();</c->
   <c- k>if</c-> <c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showA&apos;</c-><c- p>).</c->checked<c- p>)</c->
     drawAs<c- p>();</c->
   <c- k>if</c-> <c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showB&apos;</c-><c- p>).</c->checked<c- p>)</c->
     drawBs<c- p>();</c->
 <c- p>}</c->
 <c- a>function</c-> processClick<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
   <c- a>var</c-> canvas <c- o>=</c-> document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
   <c- a>var</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->
   <c- a>var</c-> x <c- o>=</c-> event<c- p>.</c->clientX<c- p>;</c->
   <c- a>var</c-> y <c- o>=</c-> event<c- p>.</c->clientY<c- p>;</c->
   <c- a>var</c-> node <c- o>=</c-> event<c- p>.</c->target<c- p>;</c->
   <c- k>while</c-> <c- p>(</c->node<c- p>)</c-> <c- p>{</c->
     x <c- o>-=</c-> node<c- p>.</c->offsetLeft <c- o>-</c-> node<c- p>.</c->scrollLeft<c- p>;</c->
     y <c- o>-=</c-> node<c- p>.</c->offsetTop <c- o>-</c-> node<c- p>.</c->scrollTop<c- p>;</c->
     node <c- o>=</c-> node<c- p>.</c->offsetParent<c- p>;</c->
   <c- p>}</c->
   drawCheckbox<c- p>(</c->context<c- p>,</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showA&apos;</c-><c- p>),</c-> <c- mf>20</c-><c- p>,</c-> <c- mf>40</c-><c- p>,</c-> <c- kc>false</c-><c- p>);</c->
   <c- k>if</c-> <c- p>(</c-><strong>context<c- p>.</c->isPointInPath<c- p>(</c->x<c- p>,</c-> y<c- p>)</c-></strong><c- p>)</c->
     document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showA&apos;</c-><c- p>).</c->checked <c- o>=</c-> <c- o>!</c-><c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showA&apos;</c-><c- p>).</c->checked<c- p>);</c->
   drawCheckbox<c- p>(</c->context<c- p>,</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showB&apos;</c-><c- p>),</c-> <c- mf>20</c-><c- p>,</c-> <c- mf>60</c-><c- p>,</c-> <c- kc>false</c-><c- p>);</c->
   <c- k>if</c-> <c- p>(</c-><strong>context<c- p>.</c->isPointInPath<c- p>(</c->x<c- p>,</c-> y<c- p>)</c-></strong><c- p>)</c->
     document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showB&apos;</c-><c- p>).</c->checked <c- o>=</c-> <c- o>!</c-><c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;showB&apos;</c-><c- p>).</c->checked<c- p>);</c->
   redraw<c- p>();</c->
 <c- p>}</c->
 document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>].</c->addEventListener<c- p>(</c-><c- t>&apos;focus&apos;</c-><c- p>,</c-> redraw<c- p>,</c-> <c- kc>true</c-><c- p>);</c->
 document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>].</c->addEventListener<c- p>(</c-><c- t>&apos;blur&apos;</c-><c- p>,</c-> redraw<c- p>,</c-> <c- kc>true</c-><c- p>);</c->
 document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>].</c->addEventListener<c- p>(</c-><c- t>&apos;change&apos;</c-><c- p>,</c-> redraw<c- p>,</c-> <c- kc>true</c-><c- p>);</c->
 document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>].</c->addEventListener<c- p>(</c-><c- t>&apos;click&apos;</c-><c- p>,</c-> processClick<c- p>,</c-> <c- kc>false</c-><c- p>);</c->
 redraw<c- p>();</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>


  </div>

  <h6 id=drawing-focus-rings-and-scrolling-paths-into-view><span class=secno>4.12.5.1.14</span> Drawing focus rings<a href=#drawing-focus-rings-and-scrolling-paths-into-view class=self-link></a></h6>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-drawfocusifneeded>drawFocusIfNeeded</span>(<var>element</var>)</code><dd>
    <p>If <var>element</var> is <a id=drawing-focus-rings-and-scrolling-paths-into-view:focused href=interaction.html#focused>focused</a>, draws a focus ring around the <a href=#current-default-path id=drawing-focus-rings-and-scrolling-paths-into-view:current-default-path>current
    default path</a>, following the platform conventions for focus rings.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-drawfocusifneeded-path-element>drawFocusIfNeeded</span>(<var>path</var>, <var>element</var>)</code><dd>
    <p>If <var>element</var> is <a id=drawing-focus-rings-and-scrolling-paths-into-view:focused-2 href=interaction.html#focused>focused</a>, draws a focus ring around <var>path</var>,
    following the platform conventions for focus rings.</p>
   </dl>

  

  <h6 id=drawing-images><span class=secno>4.12.5.1.15</span> Drawing images<a href=#drawing-images class=self-link></a></h6>

  <p>Objects that implement the <code>CanvasDrawImage</code> interface have the <dfn data-dfn-for=CanvasDrawImage id=dom-context-2d-drawimage data-dfn-type=method><code>drawImage()</code></dfn> method to
  draw images.</p>

  

  <dl class=domintro><dt><code><var>context</var>.<a href=#dom-context-2d-drawimage id=dom-context-2d-drawimage-2>drawImage</a>(<var>image</var>, <var>dx</var>, <var>dy</var>)</code><dt><code><var>context</var>.<a href=#dom-context-2d-drawimage id=drawing-images:dom-context-2d-drawimage>drawImage</a>(<var>image</var>, <var>dx</var>, <var>dy</var>, <var>dw</var>, <var>dh</var>)</code><dt><code><var>context</var>.<a href=#dom-context-2d-drawimage id=drawing-images:dom-context-2d-drawimage-2>drawImage</a>(<var>image</var>, <var>sx</var>, <var>sy</var>, <var>sw</var>, <var>sh</var>, <var>dx</var>, <var>dy</var>, <var>dw</var>, <var>dh</var>)</code><dd>
    <p>Draws the given image onto the canvas. The arguments are interpreted as follows:</p>

    <p><img alt="The sx and sy parameters give
    the x and y coordinates of the source rectangle; the sw and sh arguments give the width and
    height of the source rectangle; the dx and dy give the x and y coordinates of the destination
    rectangle; and the dw and dh arguments give the width and height of the destination
    rectangle." src=../images/drawImage.png width=356 height=356></p>

    <p>If the image isn't yet fully decoded, then nothing is drawn. If the image is a canvas with no
    data, throws an <a id=drawing-images:invalidstateerror href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a> <code id=drawing-images:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>
   </dl>

  


  <h6 id=pixel-manipulation><span class=secno>4.12.5.1.16</span> <dfn>Pixel manipulation</dfn><a href=#pixel-manipulation class=self-link></a></h6>

  <dl class=domintro><dt><code><var>imageData</var> = <var>context</var>.<span id=dom-context-2d-createimagedata-imagedata>createImageData</span>(<var>imageData</var>)</code><dd><p>Returns an <code>ImageData</code> object with the same dimensions and color space as the
   argument. All the pixels in the returned object are <a id=pixel-manipulation:transparent-black href=https://drafts.csswg.org/css-color/#transparent-black data-x-internal=transparent-black>transparent black</a>.<dt><code><var>imageData</var> = <var>context</var>.<span id=dom-context-2d-createimagedata>createImageData</span>(<var>sw</var>, <var>sh</var> [, <var>settings</var>])</code><dd>
    <p>Returns an <code>ImageData</code> object with the given dimensions. The color space of the
    returned object is the <a href=#concept-canvas-color-space id=pixel-manipulation:concept-canvas-color-space>color space</a> of
    <var>context</var> unless overridden by <var>settings</var>. All the pixels in the returned
    object are <a id=pixel-manipulation:transparent-black-2 href=https://drafts.csswg.org/css-color/#transparent-black data-x-internal=transparent-black>transparent black</a>.</p>

    <p>Throws an <a id=pixel-manipulation:indexsizeerror href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a> <code id=pixel-manipulation:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if either of
    the width or height arguments are zero.</p>
   <dt><code><var>imageData</var> = <var>context</var>.<span id=dom-context-2d-getimagedata>getImageData</span>(<var>sx</var>, <var>sy</var>, <var>sw</var>, <var>sh</var> [, <var>settings</var>])</code><dd>
    <p>Returns an <code>ImageData</code> object containing the image data for the given rectangle of
    the bitmap. The color space of the returned object is the <a href=#concept-canvas-color-space id=pixel-manipulation:concept-canvas-color-space-2>color space</a> of <var>context</var> unless overridden
    by <var>settings</var>.</p>

    <p>Throws an <a id=pixel-manipulation:indexsizeerror-2 href=https://webidl.spec.whatwg.org/#indexsizeerror data-x-internal=indexsizeerror>"<code>IndexSizeError</code>"</a> <code id=pixel-manipulation:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if the either
    of the width or height arguments are zero.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-putimagedata>putImageData</span>(<var>imageData</var>, <var>dx</var>, <var>dy</var> [, <var>dirtyX</var>, <var>dirtyY</var>, <var>dirtyWidth</var>, <var>dirtyHeight</var> ])</code><dd>
    <p>Paints the data from the given <code>ImageData</code> object onto the bitmap. If a dirty
    rectangle is provided, only the pixels from that rectangle are painted.</p>

    <p>The <code id=pixel-manipulation:dom-context-2d-globalalpha><a href=#dom-context-2d-globalalpha>globalAlpha</a></code> and <code id=pixel-manipulation:dom-context-2d-globalcompositeoperation><a href=#dom-context-2d-globalcompositeoperation>globalCompositeOperation</a></code> properties, as
    well as the <a href=#shadows id=pixel-manipulation:shadows>shadow attributes</a>, are ignored for the purposes of
    this method call; pixels in the canvas are replaced wholesale, with no composition, alpha
    blending, no shadows, etc.</p>

    <p>Throws an <a id=pixel-manipulation:invalidstateerror href=https://webidl.spec.whatwg.org/#invalidstateerror data-x-internal=invalidstateerror>"<code>InvalidStateError</code>"</a> <code id=pixel-manipulation:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if the
    <var>imageData</var> object's <code id=pixel-manipulation:dom-imagedata-data-2><a href=imagebitmap-and-animations.html#dom-imagedata-data-2>data</a></code> attribute value's
    [[ViewedArrayBuffer]] internal slot is detached.</p>
   </dl>

  

  <div class=example>
   <p>In the following example, the script generates an <code>ImageData</code> object so that it can
   draw onto it.</p>

   <pre><code class='js'><c- c1>// canvas is a reference to a &lt;canvas&gt; element</c->
<c- a>var</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->

<c- c1>// create a blank slate</c->
<c- a>var</c-> data <c- o>=</c-> context<c- p>.</c->createImageData<c- p>(</c->canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->

<c- c1>// create some plasma</c->
FillPlasma<c- p>(</c->data<c- p>,</c-> <c- t>&apos;green&apos;</c-><c- p>);</c-> <c- c1>// green plasma</c->

<c- c1>// add a cloud to the plasma</c->
AddCloud<c- p>(</c->data<c- p>,</c-> data<c- p>.</c->width<c- o>/</c-><c- mf>2</c-><c- p>,</c-> data<c- p>.</c->height<c- o>/</c-><c- mf>2</c-><c- p>);</c-> <c- c1>// put a cloud in the middle</c->

<c- c1>// paint the plasma+cloud on the canvas</c->
context<c- p>.</c->putImageData<c- p>(</c->data<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->

<c- c1>// support methods</c->
<c- a>function</c-> FillPlasma<c- p>(</c->data<c- p>,</c-> color<c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c->
<c- a>function</c-> AddCloud<c- p>(</c->data<c- p>,</c-> x<c- p>,</c-> y<c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>}</c-></code></pre>
  </div>

  <div class=example>
   <p>Here is an example of using <code id=pixel-manipulation:dom-context-2d-getimagedata><a href=#dom-context-2d-getimagedata>getImageData()</a></code> and <code id=pixel-manipulation:dom-context-2d-putimagedata><a href=#dom-context-2d-putimagedata>putImageData()</a></code> to implement an edge detection
   filter.</p>

   <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>head</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Edge detection demo<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
   <c- a>var</c-> image <c- o>=</c-> <c- k>new</c-> Image<c- p>();</c->
   <c- a>function</c-> init<c- p>()</c-> <c- p>{</c->
     image<c- p>.</c->onload <c- o>=</c-> demo<c- p>;</c->
     image<c- p>.</c->src <c- o>=</c-> <c- u>&quot;image.jpeg&quot;</c-><c- p>;</c->
   <c- p>}</c->
   <c- a>function</c-> demo<c- p>()</c-> <c- p>{</c->
     <c- a>var</c-> canvas <c- o>=</c-> document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
     <c- a>var</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->

     <c- c1>// draw the image onto the canvas</c->
     context<c- p>.</c->drawImage<c- p>(</c->image<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->

     <c- c1>// get the image data to manipulate</c->
     <c- a>var</c-> input <c- o>=</c-> context<c- p>.</c->getImageData<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->

     <c- c1>// get an empty slate to put the data into</c->
     <c- a>var</c-> output <c- o>=</c-> context<c- p>.</c->createImageData<c- p>(</c->canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->

     <c- c1>// alias some variables for convenience</c->
     <c- c1>// In this case input.width and input.height</c->
     <c- c1>// match canvas.width and canvas.height</c->
     <c- c1>// but we&apos;ll use the former to keep the code generic.</c->
     <c- a>var</c-> w <c- o>=</c-> input<c- p>.</c->width<c- p>,</c-> h <c- o>=</c-> input<c- p>.</c->height<c- p>;</c->
     <c- a>var</c-> inputData <c- o>=</c-> input<c- p>.</c->data<c- p>;</c->
     <c- a>var</c-> outputData <c- o>=</c-> output<c- p>.</c->data<c- p>;</c->

     <c- c1>// edge detection</c->
     <c- k>for</c-> <c- p>(</c-><c- a>var</c-> y <c- o>=</c-> <c- mf>1</c-><c- p>;</c-> y <c- o>&lt;</c-> h<c- o>-</c-><c- mf>1</c-><c- p>;</c-> y <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
       <c- k>for</c-> <c- p>(</c-><c- a>var</c-> x <c- o>=</c-> <c- mf>1</c-><c- p>;</c-> x <c- o>&lt;</c-> w<c- o>-</c-><c- mf>1</c-><c- p>;</c-> x <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
         <c- k>for</c-> <c- p>(</c-><c- a>var</c-> c <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> c <c- o>&lt;</c-> <c- mf>3</c-><c- p>;</c-> c <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
           <c- a>var</c-> i <c- o>=</c-> <c- p>(</c->y<c- o>*</c->w <c- o>+</c-> x<c- p>)</c-><c- o>*</c-><c- mf>4</c-> <c- o>+</c-> c<c- p>;</c->
           outputData<c- p>[</c->i<c- p>]</c-> <c- o>=</c-> <c- mf>127</c-> <c- o>+</c-> <c- o>-</c->inputData<c- p>[</c->i <c- o>-</c-> w<c- o>*</c-><c- mf>4</c-> <c- o>-</c-> <c- mf>4</c-><c- p>]</c-> <c- o>-</c->   inputData<c- p>[</c->i <c- o>-</c-> w<c- o>*</c-><c- mf>4</c-><c- p>]</c-> <c- o>-</c-> inputData<c- p>[</c->i <c- o>-</c-> w<c- o>*</c-><c- mf>4</c-> <c- o>+</c-> <c- mf>4</c-><c- p>]</c-> <c- o>+</c->
                                 <c- o>-</c->inputData<c- p>[</c->i <c- o>-</c-> <c- mf>4</c-><c- p>]</c->       <c- o>+</c-> <c- mf>8</c-><c- o>*</c->inputData<c- p>[</c->i<c- p>]</c->       <c- o>-</c-> inputData<c- p>[</c->i <c- o>+</c-> <c- mf>4</c-><c- p>]</c-> <c- o>+</c->
                                 <c- o>-</c->inputData<c- p>[</c->i <c- o>+</c-> w<c- o>*</c-><c- mf>4</c-> <c- o>-</c-> <c- mf>4</c-><c- p>]</c-> <c- o>-</c->   inputData<c- p>[</c->i <c- o>+</c-> w<c- o>*</c-><c- mf>4</c-><c- p>]</c-> <c- o>-</c-> inputData<c- p>[</c->i <c- o>+</c-> w<c- o>*</c-><c- mf>4</c-> <c- o>+</c-> <c- mf>4</c-><c- p>];</c->
         <c- p>}</c->
         outputData<c- p>[(</c->y<c- o>*</c->w <c- o>+</c-> x<c- p>)</c-><c- o>*</c-><c- mf>4</c-> <c- o>+</c-> <c- mf>3</c-><c- p>]</c-> <c- o>=</c-> <c- mf>255</c-><c- p>;</c-> <c- c1>// alpha</c->
       <c- p>}</c->
     <c- p>}</c->

     <c- c1>// put the image data back after manipulation</c->
     context<c- p>.</c->putImageData<c- p>(</c->output<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->
   <c- p>}</c->
  <c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>head</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>body</c-> <c- e>onload</c-><c- o>=</c-><c- s>&quot;init()&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>canvas</c-><c- p>&gt;&lt;/</c-><c- f>canvas</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>body</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>html</c-><c- p>&gt;</c-></code></pre>
  </div>

  <div class=example>
   <p>Here is an example of color space conversion applied when drawing a solid color and
   reading the result back using and <code id=pixel-manipulation:dom-context-2d-getimagedata-2><a href=#dom-context-2d-getimagedata>getImageData()</a></code>.</p>

   <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Color space image data demo<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>canvas</c-><c- p>&gt;&lt;/</c-><c- f>canvas</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
<c- a>const</c-> canvas <c- o>=</c-> document<c- p>.</c->querySelector<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>);</c->
<c- a>const</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>,</c-> <c- p>{</c->colorSpace<c- o>:</c-><c- t>&apos;display-p3&apos;</c-><c- p>});</c->

<c- c1>// Draw a red rectangle. Note that the hex color notation</c->
<c- c1>// specifies sRGB colors.</c->
context<c- p>.</c->fillStyle <c- o>=</c-> <c- u>&quot;#FF0000&quot;</c-><c- p>;</c->
context<c- p>.</c->fillRect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>64</c-><c- p>,</c-> <c- mf>64</c-><c- p>);</c->

<c- c1>// Get the image data.</c->
<c- a>const</c-> pixels <c- o>=</c-> context<c- p>.</c->getImageData<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>);</c->

<c- c1>// This will print &apos;display-p3&apos;, reflecting the default behavior</c->
<c- c1>// of returning image data in the canvas&apos;s color space.</c->
console<c- p>.</c->log<c- p>(</c->pixels<c- p>.</c->colorSpace<c- p>);</c->

<c- c1>// This will print the values 234, 51, and 35, reflecting the</c->
<c- c1>// red fill color, converted to &apos;display-p3&apos;.</c->
console<c- p>.</c->log<c- p>(</c->pixels<c- p>.</c->data<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
console<c- p>.</c->log<c- p>(</c->pixels<c- p>.</c->data<c- p>[</c-><c- mf>1</c-><c- p>]);</c->
console<c- p>.</c->log<c- p>(</c->pixels<c- p>.</c->data<c- p>[</c-><c- mf>2</c-><c- p>]);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>
  </div>



  <h6 id=compositing><span class=secno>4.12.5.1.17</span> Compositing<a href=#compositing class=self-link></a></h6>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-globalalpha>globalAlpha</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current <span>global alpha</span> value
    applied to rendering operations.</p>

    <p>Can be set, to change the <span>global alpha</span>
    value. Values outside of the range 0.0 .. 1.0 are ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-globalcompositeoperation>globalCompositeOperation</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the <span>current compositing and blending operator</span>, from the values defined
    in <cite>Compositing and Blending</cite>. <a href=references.html#refsCOMPOSITE>[COMPOSITE]</a></p>

    <p>Can be set, to change the <span>current compositing and blending operator</span>. Unknown
    values are ignored.</p>
   </dl>

  


  <h6 id=image-smoothing><span class=secno>4.12.5.1.18</span> Image smoothing<a href=#image-smoothing class=self-link></a></h6>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-imagesmoothingenabled>imageSmoothingEnabled</span> [ = <var>value</var> ]</code><dd>
    <p>Returns whether pattern fills and the <code id=image-smoothing:dom-context-2d-drawimage><a href=#dom-context-2d-drawimage>drawImage()</a></code> method will attempt to smooth images if
    their pixels don't line up exactly with the display, when scaling images up.</p>

    <p>Can be set, to change whether images are smoothed (true) or not (false).</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-imagesmoothingquality>imageSmoothingQuality</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current image-smoothing-quality preference.</p>

    <p>Can be set, to change the preferred quality of image smoothing. The possible values are
    "<code id=image-smoothing:dom-context-2d-imagesmoothingquality-low><a href=#dom-context-2d-imagesmoothingquality-low>low</a></code>", "<code id=image-smoothing:dom-context-2d-imagesmoothingquality-medium><a href=#dom-context-2d-imagesmoothingquality-medium>medium</a></code>" and "<code id=image-smoothing:dom-context-2d-imagesmoothingquality-high><a href=#dom-context-2d-imagesmoothingquality-high>high</a></code>". Unknown values are ignored.</p>
   </dl>

  


  <h6 id=shadows><span class=secno>4.12.5.1.19</span> <dfn>Shadows</dfn><a href=#shadows class=self-link></a></h6>

  <p>All drawing operations on an object which implements the <code>CanvasShadowStyles</code>
  interface are affected by the four global shadow attributes.</p>

  <dl class=domintro><dt><code><var>context</var>.<span id=dom-context-2d-shadowcolor>shadowColor</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current shadow color.</p>

    <p>Can be set, to change the shadow color. Values that cannot be parsed as CSS colors are
    ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-shadowoffsetx>shadowOffsetX</span> [ = <var>value</var> ]</code><dt><code><var>context</var>.<span id=dom-context-2d-shadowoffsety>shadowOffsetY</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current shadow offset.</p>

    <p>Can be set, to change the shadow offset. Values that are not finite numbers are ignored.</p>
   <dt><code><var>context</var>.<span id=dom-context-2d-shadowblur>shadowBlur</span> [ = <var>value</var> ]</code><dd>
    <p>Returns the current level of blur applied to shadows.</p>

    <p>Can be set, to change the blur level. Values that are not finite numbers greater than or
    equal to zero are ignored.</p>
   </dl>

  

  <p>If the <span>current compositing and blending operator</span> is "<code id=shadows:gcop-copy><a data-x-internal=gcop-copy href=https://drafts.fxtf.org/compositing/#porterduffcompositingoperators_src>copy</a></code>", then shadows effectively won't render (since the shape will
  overwrite the shadow).</p>

  <h6 id=filters><span class=secno>4.12.5.1.20</span> Filters<a href=#filters class=self-link></a></h6>

  <p>All drawing operations on an object which implements the <code>CanvasFilters</code>
  interface are affected by the global <dfn data-dfn-for=CanvasFilters id=dom-context-2d-filter data-dfn-type=attribute><code>filter</code></dfn> attribute.</p>

  <dl class=domintro><dt><code><var>context</var>.<a href=#dom-context-2d-filter id=dom-context-2d-filter-2>filter</a> [ = <var>value</var> ]</code><dd>
    <p>Returns the current filter.</p>


    <p>Can be set, to change the filter. Values can either be the string "<code>none</code>" or a string parseable as a <a id=filters:filter-value-list href=https://drafts.fxtf.org/filter-effects/#typedef-filter-value-list data-x-internal=filter-value-list>&lt;filter-value-list></a>. Other
    values are ignored.</p>
   </dl>

  

  <p class=note>Though <code><var>context</var>.<code id=filters:dom-context-2d-filter><a href=#dom-context-2d-filter>filter</a></code> = "<code>none</code>"</code> will disable
  filters for the context, <code><var>context</var>.<code id=filters:dom-context-2d-filter-2><a href=#dom-context-2d-filter>filter</a></code> = ""</code>, <code><var>context</var>.<code id=filters:dom-context-2d-filter-3><a href=#dom-context-2d-filter>filter</a></code> = null</code>,
  and <code><var>context</var>.<code id=filters:dom-context-2d-filter-4><a href=#dom-context-2d-filter>filter</a></code> =
  undefined</code> are all treated as unparseable inputs and the value of the <span>current filter</span> is left unchanged.</p>

  <p>Coordinates used in the value of the <span>current
  filter</span> are interpreted such that one pixel is equivalent to one SVG user space unit and to
  one canvas coordinate space unit. Filter coordinates are not affected by the <a href=#transformations id=filters:transformations>current transformation matrix</a>. The current
  transformation matrix affects only the input to the filter. Filters are applied in the
  <a href=#output-bitmap id=filters:output-bitmap>output bitmap</a>'s coordinate space.</p>

  

  <h6 id=working-with-externally-defined-svg-filters><span class=secno>4.12.5.1.21</span> Working with externally-defined SVG filters<a href=#working-with-externally-defined-svg-filters class=self-link></a></h6>

  

  <p>Since drawing is performed using filter value "<code>none</code>" until an
  externally-defined filter has finished loading, authors might wish to determine whether such a
  filter has finished loading before proceeding with a drawing operation. One way to accomplish
  this is to load the externally-defined filter elsewhere within the same page in some element that
  sends a <code>load</code> event (for example, an <a id=working-with-externally-defined-svg-filters:svg-use href=https://svgwg.org/svg2-draft/struct.html#UseElement data-x-internal=svg-use>SVG <code>use</code></a>
  element), and wait for the <code>load</code> event to be dispatched.</p>

  




  <h6 id=best-practices><span class=secno>4.12.5.1.22</span> Best practices<a href=#best-practices class=self-link></a></h6>

  <p>When a canvas is interactive, authors should include <span>focusable</span> elements in the
  element's fallback content corresponding to each <span>focusable</span> part of the canvas, as in
  the <a href=#drawCustomFocusRingExample>example above</a>.</p>

  <p>When rendering focus rings, to ensure that focus rings have the appearance of native focus
  rings, authors should use the <code id=best-practices:dom-context-2d-drawfocusifneeded><a href=#dom-context-2d-drawfocusifneeded>drawFocusIfNeeded()</a></code> method, passing it the
  element for which a ring is being drawn. This method only draws the focus ring if the element is
  <a id=best-practices:focused href=interaction.html#focused>focused</a>, so that it can simply be called whenever drawing the element, without
  checking whether the element is focused or not first.</p>

  <p id=no-text-editing-in-canvas-please>Authors should avoid implementing text editing controls
  using the <code id=best-practices:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element. Doing so has a large number of disadvantages:</p>

  <ul><li>Mouse placement of the caret has to be reimplemented.<li>Keyboard movement of the caret has to be reimplemented (possibly across lines, for multiline
   text input).<li>Scrolling of the text control has to be implemented (horizontally for long lines, vertically
   for multiline input).<li>Native features such as copy-and-paste have to be reimplemented.<li>Native features such as spell-checking have to be reimplemented.<li>Native features such as drag-and-drop have to be reimplemented.<li>Native features such as page-wide text search have to be reimplemented.<li>Native features specific to the user, for example custom text services, have to be
   reimplemented. This is close to impossible since each user might have different services
   installed, and there is an unbounded set of possible such services.<li>Bidirectional text editing has to be reimplemented.<li>For multiline text editing, line wrapping has to be implemented for all relevant
   languages.<li>Text selection has to be reimplemented.<li>Dragging of bidirectional text selections has to be reimplemented.<li>Platform-native keyboard shortcuts have to be reimplemented.<li>Platform-native input method editors (IMEs) have to be reimplemented.<li>Undo and redo functionality has to be reimplemented.<li>Accessibility features such as magnification following the caret or selection have to be
   reimplemented.</ul>

  <p>This is a huge amount of work, and authors are most strongly encouraged to avoid doing any of
  it by instead using the <code id=best-practices:the-input-element><a href=input.html#the-input-element>input</a></code> element, the <code id=best-practices:the-textarea-element><a href=form-elements.html#the-textarea-element>textarea</a></code> element, or the
  <code id=best-practices:attr-contenteditable><a href=interaction.html#attr-contenteditable>contenteditable</a></code> attribute.</p>


  <h6 id=examples><span class=secno>4.12.5.1.23</span> Examples<a href=#examples class=self-link></a></h6>

  

  <div class=example>

  <p>Here is an example of a script that uses canvas to draw <a href="data:text/html;charset=utf-8;base64,PCFET0NUWVBFIEhUTUw%2BDQo8aHRtbCBsYW5nPSJlbiI%2BDQogPGhlYWQ%2BDQogIDx0aXRsZT5QcmV0dHkgR2xvd2luZyBMaW5lczwvdGl0bGU%2BDQogPC9oZWFkPg0KIDxib2R5Pg0KPGNhbnZhcyB3aWR0aD0iODAwIiBoZWlnaHQ9IjQ1MCI%2BPC9jYW52YXM%2BDQo8c2NyaXB0Pg0KDQogdmFyIGNvbnRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnY2FudmFzJylbMF0uZ2V0Q29udGV4dCgnMmQnKTsNCg0KIHZhciBsYXN0WCA9IGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKTsNCiB2YXIgbGFzdFkgPSBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpOw0KIHZhciBodWUgPSAwOw0KIGZ1bmN0aW9uIGxpbmUoKSB7DQogICBjb250ZXh0LnNhdmUoKTsNCiAgIGNvbnRleHQudHJhbnNsYXRlKGNvbnRleHQuY2FudmFzLndpZHRoLzIsIGNvbnRleHQuY2FudmFzLmhlaWdodC8yKTsNCiAgIGNvbnRleHQuc2NhbGUoMC45LCAwLjkpOw0KICAgY29udGV4dC50cmFuc2xhdGUoLWNvbnRleHQuY2FudmFzLndpZHRoLzIsIC1jb250ZXh0LmNhbnZhcy5oZWlnaHQvMik7DQogICBjb250ZXh0LmJlZ2luUGF0aCgpOw0KICAgY29udGV4dC5saW5lV2lkdGggPSA1ICsgTWF0aC5yYW5kb20oKSAqIDEwOw0KICAgY29udGV4dC5tb3ZlVG8obGFzdFgsIGxhc3RZKTsNCiAgIGxhc3RYID0gY29udGV4dC5jYW52YXMud2lkdGggKiBNYXRoLnJhbmRvbSgpOw0KICAgbGFzdFkgPSBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpOw0KICAgY29udGV4dC5iZXppZXJDdXJ2ZVRvKGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RYLCBsYXN0WSk7DQoNCiAgIGh1ZSA9IGh1ZSArIDEwICogTWF0aC5yYW5kb20oKTsNCiAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSAnaHNsKCcgKyBodWUgKyAnLCA1MCUsIDUwJSknOw0KICAgY29udGV4dC5zaGFkb3dDb2xvciA9ICd3aGl0ZSc7DQogICBjb250ZXh0LnNoYWRvd0JsdXIgPSAxMDsNCiAgIGNvbnRleHQuc3Ryb2tlKCk7DQogICBjb250ZXh0LnJlc3RvcmUoKTsNCiB9DQogc2V0SW50ZXJ2YWwobGluZSwgNTApOw0KDQogZnVuY3Rpb24gYmxhbmsoKSB7DQogICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDAsMCwwLDAuMSknOw0KICAgY29udGV4dC5maWxsUmVjdCgwLCAwLCBjb250ZXh0LmNhbnZhcy53aWR0aCwgY29udGV4dC5jYW52YXMuaGVpZ2h0KTsNCiB9DQogc2V0SW50ZXJ2YWwoYmxhbmssIDQwKTsNCg0KPC9zY3JpcHQ%2BDQogPC9ib2R5Pg0KPC9odG1sPg0K">pretty glowing lines</a>.</p>

  <pre><code class='html'><c- p>&lt;</c-><c- f>canvas</c-> <c- e>width</c-><c- o>=</c-><c- s>&quot;800&quot;</c-> <c- e>height</c-><c- o>=</c-><c- s>&quot;450&quot;</c-><c- p>&gt;&lt;/</c-><c- f>canvas</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->

 <c- a>var</c-> context <c- o>=</c-> document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>].</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->

 <c- a>var</c-> lastX <c- o>=</c-> context<c- p>.</c->canvas<c- p>.</c->width <c- o>*</c-> Math<c- p>.</c->random<c- p>();</c->
 <c- a>var</c-> lastY <c- o>=</c-> context<c- p>.</c->canvas<c- p>.</c->height <c- o>*</c-> Math<c- p>.</c->random<c- p>();</c->
 <c- a>var</c-> hue <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
 <c- a>function</c-> line<c- p>()</c-> <c- p>{</c->
   context<c- p>.</c->save<c- p>();</c->
   context<c- p>.</c->translate<c- p>(</c->context<c- p>.</c->canvas<c- p>.</c->width<c- o>/</c-><c- mf>2</c-><c- p>,</c-> context<c- p>.</c->canvas<c- p>.</c->height<c- o>/</c-><c- mf>2</c-><c- p>);</c->
   context<c- p>.</c->scale<c- p>(</c-><c- mf>0.9</c-><c- p>,</c-> <c- mf>0.9</c-><c- p>);</c->
   context<c- p>.</c->translate<c- p>(</c-><c- o>-</c->context<c- p>.</c->canvas<c- p>.</c->width<c- o>/</c-><c- mf>2</c-><c- p>,</c-> <c- o>-</c->context<c- p>.</c->canvas<c- p>.</c->height<c- o>/</c-><c- mf>2</c-><c- p>);</c->
   context<c- p>.</c->beginPath<c- p>();</c->
   context<c- p>.</c->lineWidth <c- o>=</c-> <c- mf>5</c-> <c- o>+</c-> Math<c- p>.</c->random<c- p>()</c-> <c- o>*</c-> <c- mf>10</c-><c- p>;</c->
   context<c- p>.</c->moveTo<c- p>(</c->lastX<c- p>,</c-> lastY<c- p>);</c->
   lastX <c- o>=</c-> context<c- p>.</c->canvas<c- p>.</c->width <c- o>*</c-> Math<c- p>.</c->random<c- p>();</c->
   lastY <c- o>=</c-> context<c- p>.</c->canvas<c- p>.</c->height <c- o>*</c-> Math<c- p>.</c->random<c- p>();</c->
   context<c- p>.</c->bezierCurveTo<c- p>(</c->context<c- p>.</c->canvas<c- p>.</c->width <c- o>*</c-> Math<c- p>.</c->random<c- p>(),</c->
                         context<c- p>.</c->canvas<c- p>.</c->height <c- o>*</c-> Math<c- p>.</c->random<c- p>(),</c->
                         context<c- p>.</c->canvas<c- p>.</c->width <c- o>*</c-> Math<c- p>.</c->random<c- p>(),</c->
                         context<c- p>.</c->canvas<c- p>.</c->height <c- o>*</c-> Math<c- p>.</c->random<c- p>(),</c->
                         lastX<c- p>,</c-> lastY<c- p>);</c->

   hue <c- o>=</c-> hue <c- o>+</c-> <c- mf>10</c-> <c- o>*</c-> Math<c- p>.</c->random<c- p>();</c->
   context<c- p>.</c->strokeStyle <c- o>=</c-> <c- t>&apos;hsl(&apos;</c-> <c- o>+</c-> hue <c- o>+</c-> <c- t>&apos;, 50%, 50%)&apos;</c-><c- p>;</c->
   context<c- p>.</c->shadowColor <c- o>=</c-> <c- t>&apos;white&apos;</c-><c- p>;</c->
   context<c- p>.</c->shadowBlur <c- o>=</c-> <c- mf>10</c-><c- p>;</c->
   context<c- p>.</c->stroke<c- p>();</c->
   context<c- p>.</c->restore<c- p>();</c->
 <c- p>}</c->
 setInterval<c- p>(</c->line<c- p>,</c-> <c- mf>50</c-><c- p>);</c->

 <c- a>function</c-> blank<c- p>()</c-> <c- p>{</c->
   context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;rgba(0,0,0,0.1)&apos;</c-><c- p>;</c->
   context<c- p>.</c->fillRect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> context<c- p>.</c->canvas<c- p>.</c->width<c- p>,</c-> context<c- p>.</c->canvas<c- p>.</c->height<c- p>);</c->
 <c- p>}</c->
 setInterval<c- p>(</c->blank<c- p>,</c-> <c- mf>40</c-><c- p>);</c->

<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>

  </div>

  <div class=example>

   <p>The 2D rendering context for <code id=examples:the-canvas-element><a href=#the-canvas-element>canvas</a></code> is often used for sprite-based games. The
   following example demonstrates this:</p>

   <iframe src=../demos/canvas/blue-robot/index-idle.html width=396 height=216></iframe>

   <p>Here is the source for this example:</p>

   <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Blue Robot Demo<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>style</c-><c- p>&gt;</c->
  <c- f>html</c-> <c- p>{</c-> <c- k>overflow</c-><c- p>:</c-> <c- kc>hidden</c-><c- p>;</c-> <c- k>min-height</c-><c- p>:</c-> <c- mi>200</c-><c- b>px</c-><c- p>;</c-> <c- k>min-width</c-><c- p>:</c-> <c- mi>380</c-><c- b>px</c-><c- p>;</c-> <c- p>}</c->
  <c- f>body</c-> <c- p>{</c-> <c- k>height</c-><c- p>:</c-> <c- mi>200</c-><c- b>px</c-><c- p>;</c-> <c- k>position</c-><c- p>:</c-> <c- kc>relative</c-><c- p>;</c-> <c- k>margin</c-><c- p>:</c-> <c- mi>8</c-><c- b>px</c-><c- p>;</c-> <c- p>}</c->
  <c- p>.</c-><c- nc>buttons</c-> <c- p>{</c-> <c- k>position</c-><c- p>:</c-> <c- kc>absolute</c-><c- p>;</c-> <c- k>bottom</c-><c- p>:</c-> <c- mi>0</c-><c- b>px</c-><c- p>;</c-> <c- k>left</c-><c- p>:</c-> <c- mi>0</c-><c- b>px</c-><c- p>;</c-> <c- k>margin</c-><c- p>:</c-> <c- mi>4</c-><c- b>px</c-><c- p>;</c-> <c- p>}</c->
<c- p>&lt;/</c-><c- f>style</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>canvas</c-> <c- e>width</c-><c- o>=</c-><c- s>&quot;380&quot;</c-> <c- e>height</c-><c- o>=</c-><c- s>&quot;200&quot;</c-><c- p>&gt;&lt;/</c-><c- f>canvas</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
 <c- a>var</c-> Landscape <c- o>=</c-> <c- a>function</c-> <c- p>(</c->context<c- p>,</c-> width<c- p>,</c-> height<c- p>)</c-> <c- p>{</c->
   <c- k>this</c-><c- p>.</c->offset <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
   <c- k>this</c-><c- p>.</c->width <c- o>=</c-> width<c- p>;</c->
   <c- k>this</c-><c- p>.</c->advance <c- o>=</c-> <c- a>function</c-> <c- p>(</c->dx<c- p>)</c-> <c- p>{</c->
     <c- k>this</c-><c- p>.</c->offset <c- o>+=</c-> dx<c- p>;</c->
   <c- p>};</c->
   <c- k>this</c-><c- p>.</c->horizon <c- o>=</c-> height <c- o>*</c-> <c- mf>0.7</c-><c- p>;</c->
   <c- c1>// This creates the sky gradient (from a darker blue to white at the bottom)</c->
   <c- k>this</c-><c- p>.</c->sky <c- o>=</c-> context<c- p>.</c->createLinearGradient<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon<c- p>);</c->
   <c- k>this</c-><c- p>.</c->sky<c- p>.</c->addColorStop<c- p>(</c-><c- mf>0.0</c-><c- p>,</c-> <c- t>&apos;rgb(55,121,179)&apos;</c-><c- p>);</c->
   <c- k>this</c-><c- p>.</c->sky<c- p>.</c->addColorStop<c- p>(</c-><c- mf>0.7</c-><c- p>,</c-> <c- t>&apos;rgb(121,194,245)&apos;</c-><c- p>);</c->
   <c- k>this</c-><c- p>.</c->sky<c- p>.</c->addColorStop<c- p>(</c-><c- mf>1.0</c-><c- p>,</c-> <c- t>&apos;rgb(164,200,214)&apos;</c-><c- p>);</c->
   <c- c1>// this creates the grass gradient (from a darker green to a lighter green)</c->
   <c- k>this</c-><c- p>.</c->earth <c- o>=</c-> context<c- p>.</c->createLinearGradient<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> height<c- p>);</c->
   <c- k>this</c-><c- p>.</c->earth<c- p>.</c->addColorStop<c- p>(</c-><c- mf>0.0</c-><c- p>,</c-> <c- t>&apos;rgb(81,140,20)&apos;</c-><c- p>);</c->
   <c- k>this</c-><c- p>.</c->earth<c- p>.</c->addColorStop<c- p>(</c-><c- mf>1.0</c-><c- p>,</c-> <c- t>&apos;rgb(123,177,57)&apos;</c-><c- p>);</c->
   <c- k>this</c-><c- p>.</c->paintBackground <c- o>=</c-> <c- a>function</c-> <c- p>(</c->context<c- p>,</c-> width<c- p>,</c-> height<c- p>)</c-> <c- p>{</c->
     <c- c1>// first, paint the sky and grass rectangles</c->
     context<c- p>.</c->fillStyle <c- o>=</c-> <c- k>this</c-><c- p>.</c->sky<c- p>;</c->
     context<c- p>.</c->fillRect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> width<c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon<c- p>);</c->
     context<c- p>.</c->fillStyle <c- o>=</c-> <c- k>this</c-><c- p>.</c->earth<c- p>;</c->
     context<c- p>.</c->fillRect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon<c- p>,</c-> width<c- p>,</c-> height<c- o>-</c-><c- k>this</c-><c- p>.</c->horizon<c- p>);</c->
     <c- c1>// then, draw the cloudy banner</c->
     <c- c1>// we make it cloudy by having the draw text off the top of the</c->
     <c- c1>// canvas, and just having the blurred shadow shown on the canvas</c->
     context<c- p>.</c->save<c- p>();</c->
     context<c- p>.</c->translate<c- p>(</c->width<c- o>-</c-><c- p>((</c-><c- k>this</c-><c- p>.</c->offset<c- o>+</c-><c- p>(</c-><c- k>this</c-><c- p>.</c->width<c- o>*</c-><c- mf>3.2</c-><c- p>))</c-> <c- o>%</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->width<c- o>*</c-><c- mf>4.0</c-><c- p>))</c-><c- o>+</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->
     context<c- p>.</c->shadowColor <c- o>=</c-> <c- t>&apos;white&apos;</c-><c- p>;</c->
     context<c- p>.</c->shadowOffsetY <c- o>=</c-> <c- mf>30</c-><c- o>+</c-><c- k>this</c-><c- p>.</c->horizon<c- o>/</c-><c- mf>3</c-><c- p>;</c-> <c- c1>// offset down on canvas</c->
     context<c- p>.</c->shadowBlur <c- o>=</c-> <c- t>&apos;5&apos;</c-><c- p>;</c->
     context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;white&apos;</c-><c- p>;</c->
     context<c- p>.</c->textAlign <c- o>=</c-> <c- t>&apos;left&apos;</c-><c- p>;</c->
     context<c- p>.</c->textBaseline <c- o>=</c-> <c- t>&apos;top&apos;</c-><c- p>;</c->
     context<c- p>.</c->font <c- o>=</c-> <c- t>&apos;20px sans-serif&apos;</c-><c- p>;</c->
     context<c- p>.</c->fillText<c- p>(</c-><c- t>&apos;WHATWG ROCKS&apos;</c-><c- p>,</c-> <c- mf>10</c-><c- p>,</c-> <c- o>-</c-><c- mf>30</c-><c- p>);</c-> <c- c1>// text up above canvas</c->
     context<c- p>.</c->restore<c- p>();</c->
     <c- c1>// then, draw the background tree</c->
     context<c- p>.</c->save<c- p>();</c->
     context<c- p>.</c->translate<c- p>(</c->width<c- o>-</c-><c- p>((</c-><c- k>this</c-><c- p>.</c->offset<c- o>+</c-><c- p>(</c-><c- k>this</c-><c- p>.</c->width<c- o>*</c-><c- mf>0.2</c-><c- p>))</c-> <c- o>%</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->width<c- o>*</c-><c- mf>1.5</c-><c- p>))</c-><c- o>+</c-><c- mf>30</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->
     context<c- p>.</c->beginPath<c- p>();</c->
     context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;rgb(143,89,2)&apos;</c-><c- p>;</c->
     context<c- p>.</c->lineStyle <c- o>=</c-> <c- t>&apos;rgb(10,10,10)&apos;</c-><c- p>;</c->
     context<c- p>.</c->lineWidth <c- o>=</c-> <c- mf>2</c-><c- p>;</c->
     context<c- p>.</c->rect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon<c- o>+</c-><c- mf>5</c-><c- p>,</c-> <c- mf>10</c-><c- p>,</c-> <c- o>-</c-><c- mf>50</c-><c- p>);</c-> <c- c1>// trunk</c->
     context<c- p>.</c->fill<c- p>();</c->
     context<c- p>.</c->stroke<c- p>();</c->
     context<c- p>.</c->beginPath<c- p>();</c->
     context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;rgb(78,154,6)&apos;</c-><c- p>;</c->
     context<c- p>.</c->arc<c- p>(</c-><c- mf>5</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon<c- o>-</c-><c- mf>60</c-><c- p>,</c-> <c- mf>30</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> Math<c- p>.</c->PI<c- o>*</c-><c- mf>2</c-><c- p>);</c-> <c- c1>// leaves</c->
     context<c- p>.</c->fill<c- p>();</c->
     context<c- p>.</c->stroke<c- p>();</c->
     context<c- p>.</c->restore<c- p>();</c->
   <c- p>};</c->
   <c- k>this</c-><c- p>.</c->paintForeground <c- o>=</c-> <c- a>function</c-> <c- p>(</c->context<c- p>,</c-> width<c- p>,</c-> height<c- p>)</c-> <c- p>{</c->
     <c- c1>// draw the box that goes in front</c->
     context<c- p>.</c->save<c- p>();</c->
     context<c- p>.</c->translate<c- p>(</c->width<c- o>-</c-><c- p>((</c-><c- k>this</c-><c- p>.</c->offset<c- o>+</c-><c- p>(</c-><c- k>this</c-><c- p>.</c->width<c- o>*</c-><c- mf>0.7</c-><c- p>))</c-> <c- o>%</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->width<c- o>*</c-><c- mf>1.1</c-><c- p>))</c-><c- o>+</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->
     context<c- p>.</c->beginPath<c- p>();</c->
     context<c- p>.</c->rect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->horizon <c- o>-</c-> <c- mf>5</c-><c- p>,</c-> <c- mf>25</c-><c- p>,</c-> <c- mf>25</c-><c- p>);</c->
     context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;rgb(220,154,94)&apos;</c-><c- p>;</c->
     context<c- p>.</c->lineStyle <c- o>=</c-> <c- t>&apos;rgb(10,10,10)&apos;</c-><c- p>;</c->
     context<c- p>.</c->lineWidth <c- o>=</c-> <c- mf>2</c-><c- p>;</c->
     context<c- p>.</c->fill<c- p>();</c->
     context<c- p>.</c->stroke<c- p>();</c->
     context<c- p>.</c->restore<c- p>();</c->
   <c- p>};</c->
 <c- p>};</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
 <c- a>var</c-> BlueRobot <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c->
   <c- k>this</c-><c- p>.</c->sprites <c- o>=</c-> <c- k>new</c-> Image<c- p>();</c->
   <c- k>this</c-><c- p>.</c->sprites<c- p>.</c->src <c- o>=</c-> <c- t>&apos;blue-robot.png&apos;</c-><c- p>;</c-> <c- c1>// this sprite sheet has 8 cells</c->
   <c- k>this</c-><c- p>.</c->targetMode <c- o>=</c-> <c- t>&apos;idle&apos;</c-><c- p>;</c->
   <c- k>this</c-><c- p>.</c->walk <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c->
     <c- k>this</c-><c- p>.</c->targetMode <c- o>=</c-> <c- t>&apos;walk&apos;</c-><c- p>;</c->
   <c- p>};</c->
   <c- k>this</c-><c- p>.</c->stop <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c->
     <c- k>this</c-><c- p>.</c->targetMode <c- o>=</c-> <c- t>&apos;idle&apos;</c-><c- p>;</c->
   <c- p>};</c->
   <c- k>this</c-><c- p>.</c->frameIndex <c- o>=</c-> <c- p>{</c->
     <c- t>&apos;idle&apos;</c-><c- o>:</c-> <c- p>[</c-><c- mf>0</c-><c- p>],</c-> <c- c1>// first cell is the idle frame</c->
     <c- t>&apos;walk&apos;</c-><c- o>:</c-> <c- p>[</c-><c- mf>1</c-><c- p>,</c-><c- mf>2</c-><c- p>,</c-><c- mf>3</c-><c- p>,</c-><c- mf>4</c-><c- p>,</c-><c- mf>5</c-><c- p>,</c-><c- mf>6</c-><c- p>],</c-> <c- c1>// the walking animation is cells 1-6</c->
     <c- t>&apos;stop&apos;</c-><c- o>:</c-> <c- p>[</c-><c- mf>7</c-><c- p>],</c-> <c- c1>// last cell is the stopping animation</c->
   <c- p>};</c->
   <c- k>this</c-><c- p>.</c->mode <c- o>=</c-> <c- t>&apos;idle&apos;</c-><c- p>;</c->
   <c- k>this</c-><c- p>.</c->frame <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> <c- c1>// index into frameIndex</c->
   <c- k>this</c-><c- p>.</c->tick <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c->
     <c- c1>// this advances the frame and the robot</c->
     <c- c1>// the return value is how many pixels the robot has moved</c->
     <c- k>this</c-><c- p>.</c->frame <c- o>+=</c-> <c- mf>1</c-><c- p>;</c->
     <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->frame <c- o>&gt;=</c-> <c- k>this</c-><c- p>.</c->frameIndex<c- p>[</c-><c- k>this</c-><c- p>.</c->mode<c- p>].</c->length<c- p>)</c-> <c- p>{</c->
       <c- c1>// we&apos;ve reached the end of this animation cycle</c->
       <c- k>this</c-><c- p>.</c->frame <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
       <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->mode <c- o>!=</c-> <c- k>this</c-><c- p>.</c->targetMode<c- p>)</c-> <c- p>{</c->
         <c- c1>// switch to next cycle</c->
         <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->mode <c- o>==</c-> <c- t>&apos;walk&apos;</c-><c- p>)</c-> <c- p>{</c->
           <c- c1>// we need to stop walking before we decide what to do next</c->
           <c- k>this</c-><c- p>.</c->mode <c- o>=</c-> <c- t>&apos;stop&apos;</c-><c- p>;</c->
         <c- p>}</c-> <c- k>else</c-> <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->mode <c- o>==</c-> <c- t>&apos;stop&apos;</c-><c- p>)</c-> <c- p>{</c->
           <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->targetMode <c- o>==</c-> <c- t>&apos;walk&apos;</c-><c- p>)</c->
             <c- k>this</c-><c- p>.</c->mode <c- o>=</c-> <c- t>&apos;walk&apos;</c-><c- p>;</c->
           <c- k>else</c->
             <c- k>this</c-><c- p>.</c->mode <c- o>=</c-> <c- t>&apos;idle&apos;</c-><c- p>;</c->
         <c- p>}</c-> <c- k>else</c-> <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->mode <c- o>==</c-> <c- t>&apos;idle&apos;</c-><c- p>)</c-> <c- p>{</c->
           <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->targetMode <c- o>==</c-> <c- t>&apos;walk&apos;</c-><c- p>)</c->
             <c- k>this</c-><c- p>.</c->mode <c- o>=</c-> <c- t>&apos;walk&apos;</c-><c- p>;</c->
         <c- p>}</c->
       <c- p>}</c->
     <c- p>}</c->
     <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->mode <c- o>==</c-> <c- t>&apos;walk&apos;</c-><c- p>)</c->
       <c- k>return</c-> <c- mf>8</c-><c- p>;</c->
     <c- k>return</c-> <c- mf>0</c-><c- p>;</c->
   <c- p>},</c->
   <c- k>this</c-><c- p>.</c->paint <c- o>=</c-> <c- a>function</c-> <c- p>(</c->context<c- p>,</c-> x<c- p>,</c-> y<c- p>)</c-> <c- p>{</c->
     <c- k>if</c-> <c- p>(</c-><c- o>!</c-><c- k>this</c-><c- p>.</c->sprites<c- p>.</c->complete<c- p>)</c-> <c- k>return</c-><c- p>;</c->
     <c- c1>// draw the right frame out of the sprite sheet onto the canvas</c->
     <c- c1>// we assume each frame is as high as the sprite sheet</c->
     <c- c1>// the x,y coordinates give the position of the bottom center of the sprite</c->
     context<c- p>.</c->drawImage<c- p>(</c-><c- k>this</c-><c- p>.</c->sprites<c- p>,</c->
                       <c- k>this</c-><c- p>.</c->frameIndex<c- p>[</c-><c- k>this</c-><c- p>.</c->mode<c- p>][</c-><c- k>this</c-><c- p>.</c->frame<c- p>]</c-> <c- o>*</c-> <c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- p>,</c-> <c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- p>,</c->
                       x<c- o>-</c-><c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- o>/</c-><c- mf>2</c-><c- p>,</c-> y<c- o>-</c-><c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- p>,</c-> <c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- p>,</c-> <c- k>this</c-><c- p>.</c->sprites<c- p>.</c->height<c- p>);</c->
   <c- p>};</c->
 <c- p>};</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
 <c- a>var</c-> canvas <c- o>=</c-> document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
 <c- a>var</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->
 <c- a>var</c-> landscape <c- o>=</c-> <c- k>new</c-> Landscape<c- p>(</c->context<c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->
 <c- a>var</c-> blueRobot <c- o>=</c-> <c- k>new</c-> BlueRobot<c- p>();</c->
 <c- c1>// paint when the browser wants us to, using requestAnimationFrame()</c->
 <c- a>function</c-> paint<c- p>()</c-> <c- p>{</c->
   context<c- p>.</c->clearRect<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->
   landscape<c- p>.</c->paintBackground<c- p>(</c->context<c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->
   blueRobot<c- p>.</c->paint<c- p>(</c->context<c- p>,</c-> canvas<c- p>.</c->width<c- o>/</c-><c- mf>2</c-><c- p>,</c-> landscape<c- p>.</c->horizon<c- o>*</c-><c- mf>1.1</c-><c- p>);</c->
   landscape<c- p>.</c->paintForeground<c- p>(</c->context<c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->
   requestAnimationFrame<c- p>(</c->paint<c- p>);</c->
 <c- p>}</c->
 paint<c- p>();</c->
 <c- c1>// but tick every 100ms, so that we don&apos;t slow down when we don&apos;t paint</c->
 setInterval<c- p>(</c-><c- a>function</c-> <c- p>()</c-> <c- p>{</c->
   <c- a>var</c-> dx <c- o>=</c-> blueRobot<c- p>.</c->tick<c- p>();</c->
   landscape<c- p>.</c->advance<c- p>(</c->dx<c- p>);</c->
 <c- p>},</c-> <c- mf>100</c-><c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>p</c-> <c- e>class</c-><c- o>=</c-><c- s>&quot;buttons&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;Walk&quot;</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;blueRobot.walk()&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;Stop&quot;</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;blueRobot.stop()&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>footer</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>small</c-><c- p>&gt;</c-> Blue Robot Player Sprite by <c- p>&lt;</c-><c- f>a</c-> <c- e>href</c-><c- o>=</c-><c- s>&quot;https://johncolburn.deviantart.com/&quot;</c-><c- p>&gt;</c->JohnColburn<c- p>&lt;/</c-><c- f>a</c-><c- p>&gt;</c->.
 Licensed under the terms of the Creative Commons Attribution Share-Alike 3.0 Unported license.<c- p>&lt;/</c-><c- f>small</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>small</c-><c- p>&gt;</c-> This work is itself licensed under a <c- p>&lt;</c-><c- f>a</c-> <c- e>rel</c-><c- o>=</c-><c- s>&quot;license&quot;</c-> <c- e>href</c-><c- o>=</c-><c- s>&quot;https://creativecommons.org/licenses/by-sa/3.0/&quot;</c-><c- p>&gt;</c->Creative
 Commons Attribution-ShareAlike 3.0 Unported License<c- p>&lt;/</c-><c- f>a</c-><c- p>&gt;</c->.<c- p>&lt;/</c-><c- f>small</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>footer</c-><c- p>&gt;</c->
</code></pre>

  </div>




  <h5 id=the-imagebitmap-rendering-context><span class=secno>4.12.5.2</span> The <code>ImageBitmap</code> rendering context<a href=#the-imagebitmap-rendering-context class=self-link></a></h5>

  <h6 id=introduction-5><span class=secno>4.12.5.2.1</span> Introduction<a href=#introduction-5 class=self-link></a></h6>

  <p><code>ImageBitmapRenderingContext</code> is a performance-oriented interface that provides a
  low overhead method for displaying the contents of <code>ImageBitmap</code> objects. It uses
  transfer semantics to reduce overall memory consumption. It also streamlines performance by
  avoiding intermediate compositing, unlike the <code id=introduction-5:dom-context-2d-drawimage><a href=#dom-context-2d-drawimage>drawImage()</a></code> method of
  <code>CanvasRenderingContext2D</code>.</p>

  <p>Using an <code id=introduction-5:the-img-element><a href=embedded-content.html#the-img-element>img</a></code> element as an intermediate for getting an image resource into a
  canvas, for example, would result in two copies of the decoded image existing in memory at the
  same time: the <code id=introduction-5:the-img-element-2><a href=embedded-content.html#the-img-element>img</a></code> element's copy, and the one in the canvas's backing store. This
  memory cost can be prohibitive when dealing with extremely large images. This can be avoided by
  using <code>ImageBitmapRenderingContext</code>.</p>

  <div class=example>
   <p>Using <code>ImageBitmapRenderingContext</code>, here is how to transcode an image to the JPEG
   format in a memory- and CPU-efficient way:</p>

   <pre><code class='js'>createImageBitmap<c- p>(</c->inputImageBlob<c- p>).</c->then<c- p>(</c->image <c- p>=&gt;</c-> <c- p>{</c->
  <c- a>const</c-> canvas <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;canvas&apos;</c-><c- p>);</c->
  <c- a>const</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;bitmaprenderer&apos;</c-><c- p>);</c->
  context<c- p>.</c->transferFromImageBitmap<c- p>(</c->image<c- p>);</c->

  canvas<c- p>.</c->toBlob<c- p>(</c->outputJPEGBlob <c- p>=&gt;</c-> <c- p>{</c->
    <c- c1>// Do something with outputJPEGBlob.</c->
  <c- p>},</c-> <c- t>&apos;image/jpeg&apos;</c-><c- p>);</c->
<c- p>});</c-></code></pre>
  </div>

  <h6 id=the-imagebitmaprenderingcontext-interface><span class=secno>4.12.5.2.2</span> The <code>ImageBitmapRenderingContext</code> interface<a href=#the-imagebitmaprenderingcontext-interface class=self-link></a></h6><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmapRenderingContext title="The ImageBitmapRenderingContext interface is a canvas rendering context that provides the functionality to replace the canvas's contents with the given ImageBitmap. Its context id (the first argument to HTMLCanvasElement.getContext() or OffscreenCanvas.getContext()) is &quot;bitmaprenderer&quot;.">ImageBitmapRenderingContext</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>46+</span></span><span class="safari yes"><span>Safari</span><span>11.1+</span></span><span class="chrome yes"><span>Chrome</span><span>66+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  

  <dl class=domintro><dt><code><var>context</var> = <var>canvas</var>.<a href=#dom-canvas-getcontext id=the-imagebitmaprenderingcontext-interface:dom-canvas-getcontext>getContext</a>('bitmaprenderer' [, { [ <span>alpha</span>: false ] } ])</code><dd>
    <p>Returns an <code>ImageBitmapRenderingContext</code> object that is permanently bound to a
    particular <code id=the-imagebitmaprenderingcontext-interface:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element.</p>

    <p>If the <code>alpha</code> setting is
    provided and set to false, then the canvas is forced to always be opaque.</p>
   <dt><code><var>context</var>.<span id=dom-imagebitmaprenderingcontext-canvas>canvas</span></code><dd><p>Returns the <code id=the-imagebitmaprenderingcontext-interface:the-canvas-element-2><a href=#the-canvas-element>canvas</a></code> element that the context is bound to.<dt><code><var>context</var>.<span id=dom-imagebitmaprenderingcontext-transferfromimagebitmap>transferFromImageBitmap</span>(imageBitmap)</code><dd>
    <p>Transfers the underlying <span>bitmap data</span>
    from <var>imageBitmap</var> to <var>context</var>, and the bitmap becomes the contents of the
    <code id=the-imagebitmaprenderingcontext-interface:the-canvas-element-3><a href=#the-canvas-element>canvas</a></code> element to which <var>context</var> is bound.</p>
   <dt><code><var>context</var>.<a href=#dom-imagebitmaprenderingcontext-transferfromimagebitmap id=the-imagebitmaprenderingcontext-interface:dom-imagebitmaprenderingcontext-transferfromimagebitmap>transferFromImageBitmap</a>(null)</code><dd>
    <p>Replaces contents of the <code id=the-imagebitmaprenderingcontext-interface:the-canvas-element-4><a href=#the-canvas-element>canvas</a></code> element to which <var>context</var> is bound
    with a <a id=the-imagebitmaprenderingcontext-interface:transparent-black href=https://drafts.csswg.org/css-color/#transparent-black data-x-internal=transparent-black>transparent black</a> bitmap whose size corresponds to the <code id=the-imagebitmaprenderingcontext-interface:attr-canvas-width><a href=#attr-canvas-width>width</a></code> and <code id=the-imagebitmaprenderingcontext-interface:attr-canvas-height><a href=#attr-canvas-height>height</a></code>
    content attributes of the <code id=the-imagebitmaprenderingcontext-interface:the-canvas-element-5><a href=#the-canvas-element>canvas</a></code> element.</p>
   </dl>

  




  <h5 id=the-offscreencanvas-interface><span class=secno>4.12.5.3</span> The <code>OffscreenCanvas</code> interface<a href=#the-offscreencanvas-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas title="When using the <canvas> element or the Canvas API, rendering, animation, and user interaction usually happen on the main execution thread of a web application. The computation relating to canvas animations and rendering can have a significant impact on application performance.">OffscreenCanvas</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>105+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>69+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  

  <p class=note><code>OffscreenCanvas</code> is an <code id=the-offscreencanvas-interface:eventtarget><a data-x-internal=eventtarget href=https://dom.spec.whatwg.org/#interface-eventtarget>EventTarget</a></code>, so both
  <code>OffscreenCanvasRenderingContext2D</code> and WebGL can fire events at it.
  <code>OffscreenCanvasRenderingContext2D</code> can fire <code id=the-offscreencanvas-interface:event-contextlost><a href=indices.html#event-contextlost>contextlost</a></code> and <code id=the-offscreencanvas-interface:event-contextrestored><a href=indices.html#event-contextrestored>contextrestored</a></code>, and WebGL can fire <code>webglcontextlost</code> and <code>webglcontextrestored</code>.
  <a href=references.html#refsWEBGL>[WEBGL]</a></p>

  <p><code>OffscreenCanvas</code> objects are used to create rendering contexts, much like an
  <code>HTMLCanvasElement</code>, but with no connection to the DOM. This makes it possible to
  use canvas rendering contexts in <a href=workers.html#workers>workers</a>.</p>

  <p>An <code>OffscreenCanvas</code> object may hold a weak reference to a <dfn id=offscreencanvas-placeholder>placeholder <code>canvas</code> element</dfn>, which is
  typically in the DOM, whose embedded content is provided by the <code>OffscreenCanvas</code>
  object. The bitmap of the <code>OffscreenCanvas</code> object is pushed to the <a href=#offscreencanvas-placeholder id=the-offscreencanvas-interface:offscreencanvas-placeholder>placeholder <code>canvas</code> element</a> as part of
  the <code>OffscreenCanvas</code>'s <span>relevant agent</span>'s <a href=webappapis.html#concept-agent-event-loop id=the-offscreencanvas-interface:concept-agent-event-loop>event loop</a>'s <span>update the rendering</span>
  steps.</p>

  <dl class=domintro><dt><code><var>offscreenCanvas</var> = new <span id=dom-offscreencanvas>OffscreenCanvas</span>(<var>width</var>,
   <var>height</var>)</code><dd>
    <p>Returns a new <code>OffscreenCanvas</code> object that is not linked to a <a href=#offscreencanvas-placeholder id=the-offscreencanvas-interface:offscreencanvas-placeholder-2>placeholder <code>canvas</code> element</a>, and whose
    bitmap's size is determined by the <var>width</var> and <var>height</var> arguments.</p>
   <dt><code><var>context</var> = <var>offscreenCanvas</var>.<span id=dom-offscreencanvas-getcontext>getContext</span>(<var>contextId</var> [,
   <var>options</var> ])</code><dd>
    <p>Returns an object that exposes an API for drawing on the <code>OffscreenCanvas</code> object.
    <var>contextId</var> specifies the desired API: "<code>2d</code>", "<code>bitmaprenderer</code>", "<code>webgl</code>", "<code>webgl2</code>", or "<code>webgpu</code>". <var>options</var> is handled by that
    API.</p>

    <p>This specification defines the "<code>2d</code>" context below,
    which is similar but distinct from the "<code>2d</code>"
    context that is created from a <code id=the-offscreencanvas-interface:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element. The WebGL specifications define the
    "<code>webgl</code>" and "<code>webgl2</code>" contexts. <cite>WebGPU</cite> defines the
    "<code>webgpu</code>" context. <a href=references.html#refsWEBGL>[WEBGL]</a>
    <a href=references.html#refsWEBGPU>[WEBGPU]</a></p>

    <p>Returns null if the canvas has already been initialized with another context type (e.g.,
    trying to get a "<code>2d</code>" context after getting a
    "<code>webgl</code>" context).</p>
   </dl>

  

  <dl class=domintro><dt><code><var>offscreenCanvas</var>.<span id=dom-offscreencanvas-width>width</span> [
   = <var>value</var> ]</code><dt><code><var>offscreenCanvas</var>.<span id=dom-offscreencanvas-height>height</span> [
   = <var>value</var> ]</code><dd>
    <p>These attributes return the dimensions of the <code>OffscreenCanvas</code> object's <span>bitmap</span>.</p>

    <p>They can be set, to replace the <span>bitmap</span> with a
    new, <a id=the-offscreencanvas-interface:transparent-black href=https://drafts.csswg.org/css-color/#transparent-black data-x-internal=transparent-black>transparent black</a> bitmap of the specified dimensions (effectively resizing
    it).</p>
   </dl>

  

  <p class=note>If an <code>OffscreenCanvas</code> object whose dimensions were changed has
  a <a href=#offscreencanvas-placeholder id=the-offscreencanvas-interface:offscreencanvas-placeholder-3>placeholder <code>canvas</code> element</a>, then
  the <a href=#offscreencanvas-placeholder id=the-offscreencanvas-interface:offscreencanvas-placeholder-4>placeholder <code>canvas</code> element</a>'s
  <a href=https://drafts.csswg.org/css-images/#natural-dimensions id=the-offscreencanvas-interface:natural-dimensions data-x-internal=natural-dimensions>natural size</a> will only be updated during the
  <code>OffscreenCanvas</code>'s <span>relevant agent</span>'s <a href=webappapis.html#concept-agent-event-loop id=the-offscreencanvas-interface:concept-agent-event-loop-2>event loop</a>'s <span>update the rendering</span> steps.</p>

  <dl class=domintro><dt><code><var>promise</var> = <var>offscreenCanvas</var>.<span id=dom-offscreencanvas-converttoblob>convertToBlob</span>([<var>options</var>])</code><dd>
    <p>Returns a promise that will fulfill with a new <code id=the-offscreencanvas-interface:blob><a data-x-internal=blob href=https://w3c.github.io/FileAPI/#dfn-Blob>Blob</a></code> object representing a file
    containing the image in the <code>OffscreenCanvas</code> object.</p>

    <p>The argument, if provided, is a dictionary that controls the encoding options of the image
    file to be created. The <code>type</code> field specifies the
    file format and has a default value of "<code id=the-offscreencanvas-interface:image/png><a href=indices.html#image/png>image/png</a></code>"; that type is also used if the
    requested type isn't supported. If the image format supports variable quality (such as
    "<code id=the-offscreencanvas-interface:image/jpeg><a href=indices.html#image/jpeg>image/jpeg</a></code>"), then the <code>quality</code>
    field is a number in the range 0.0 to 1.0 inclusive indicating the desired quality level for the
    resulting image.</p>
   <dt><code><var>canvas</var>.<span id=dom-offscreencanvas-transfertoimagebitmap>transferToImageBitmap</span>()</code><dd>
    <p>Returns a newly created <code>ImageBitmap</code> object with the image in the
    <code>OffscreenCanvas</code> object. The image in the <code>OffscreenCanvas</code> object is
    replaced with a new blank image.</p>
   </dl>

  

  <p>The following are the <a id=the-offscreencanvas-interface:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <span>event handler event types</span>)  supported,
  as <a id=the-offscreencanvas-interface:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by all objects implementing the
  <code>OffscreenCanvas</code> interface:</p>

  <table><thead><tr><th><a href=webappapis.html#event-handlers id=the-offscreencanvas-interface:event-handlers-2>Event handler</a> <th><span>Event handler event type</span>
   <tbody><tr><td><dfn data-dfn-for=OffscreenCanvas id=handler-offscreencanvas-oncontextlost data-dfn-type=attribute><code>oncontextlost</code></dfn> <td> <code id=the-offscreencanvas-interface:event-contextlost-2><a href=indices.html#event-contextlost>contextlost</a></code>
    <tr><td><dfn data-dfn-for=OffscreenCanvas id=handler-offscreencanvas-oncontextrestored data-dfn-type=attribute><code>oncontextrestored</code></dfn> <td> <code id=the-offscreencanvas-interface:event-contextrestored-2><a href=indices.html#event-contextrestored>contextrestored</a></code>
  </table>

  <h6 id=the-offscreen-2d-rendering-context><span class=secno>4.12.5.3.1</span> The offscreen 2D rendering context<a href=#the-offscreen-2d-rendering-context class=self-link></a></h6><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D title="The OffscreenCanvasRenderingContext2D interface is a CanvasRenderingContext2D rendering context for drawing to the bitmap of an OffscreenCanvas object. It is similar to the CanvasRenderingContext2D object, with the following differences:">OffscreenCanvasRenderingContext2D</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>105+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>69+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  

  <p>The <code>OffscreenCanvasRenderingContext2D</code> object is a rendering context for drawing to
  the <span>bitmap</span> of an <code>OffscreenCanvas</code> object.
  It is similar to the <code>CanvasRenderingContext2D</code> object, with the following
  differences:</p>

  <ul><li><p>there is no support for <span>user interface</span>
   features;<li><p>its <code id=the-offscreen-2d-rendering-context:offscreencontext2d-canvas><a href=#offscreencontext2d-canvas>canvas</a></code> attribute refers to an
   <code>OffscreenCanvas</code> object rather than a <code id=the-offscreen-2d-rendering-context:the-canvas-element><a href=#the-canvas-element>canvas</a></code> element;</ul>

  <p>An <code>OffscreenCanvasRenderingContext2D</code> object has an <dfn id=associated-offscreencanvas-object>associated
  <code>OffscreenCanvas</code> object</dfn>, which is the <code>OffscreenCanvas</code> object
  from which the <code>OffscreenCanvasRenderingContext2D</code> object was created.

  <dl class=domintro><dt><code><var>offscreenCanvas</var> = <var>offscreenCanvasRenderingContext2D</var>.<span id=offscreencontext2d-canvas>canvas</span></code><dd><p>Returns the <a href=#associated-offscreencanvas-object id=the-offscreen-2d-rendering-context:associated-offscreencanvas-object>associated <code>OffscreenCanvas</code> object</a>.</dl>

  

  



  <h5 id=serialising-bitmaps-to-a-file><span class=secno>4.12.5.4</span> Serializing bitmaps to a file<a href=#serialising-bitmaps-to-a-file class=self-link></a></h5>

  


  

  <h5 id=premultiplied-alpha-and-the-2d-rendering-context><span class=secno>4.12.5.5</span> Premultiplied alpha and the 2D rendering context<a href=#premultiplied-alpha-and-the-2d-rendering-context class=self-link></a></h5>

  <p><dfn id=concept-premultiplied-alpha>Premultiplied alpha</dfn> refers to one way of
  representing transparency in an image, the other being non-premultiplied alpha.</p>

  <p>Under non-premultiplied alpha, the red, green, and blue components of a pixel represent that
  pixel's color, and its alpha component represents that pixel's opacity.</p>

  <p>Under premultiplied alpha, however, the red, green, and blue components of a pixel represent
  the amounts of color that the pixel adds to the image, and its alpha component represents the
  amount that the pixel obscures whatever is behind it.</p>

  <div class=example>
   <p>For instance, assuming the color components range from 0 (off) to 255 (full intensity), these
   example colors are represented in the following ways:</p>

   <table><thead><tr><th>CSS color representation
      <th>Premultiplied representation
      <th>Non-premultiplied representation
      <th>Description of color
      <th>Image of color blended above other content
    <tbody><tr><td>rgba(255, 127, 0, 1)
      <td>255, 127, 0, 255
      <td>255, 127, 0, 255
      <td>Completely-opaque orange
      <td><img alt="An opaque orange circle sits atop a background" src=images/premultiplied-example-1.html width=96 height=96>
     <tr><td>rgba(255, 255, 0, 0.5)
      <td>127, 127, 0, 127
      <td>255, 255, 0, 127
      <td>Halfway-opaque yellow
      <td><img alt="A yellow circle, halfway transparent, sits atop a background" src=images/premultiplied-example-2.html width=96 height=96>
     <tr><td>Unrepresentable
      <td>255, 127, 0, 127
      <td>Unrepresentable
      <td>Additive halfway-opaque orange
      <td><img alt="An orange circle somewhat brightens the background that it sits atop" src=images/premultiplied-example-3.html width=96 height=96>
     <tr><td>Unrepresentable
      <td>255, 127, 0, 0
      <td>Unrepresentable
      <td>Additive fully-transparent orange
      <td><img alt="An orange circle completely brightens the background that it sits atop" src=images/premultiplied-example-4.html width=96 height=96>
     <tr><td>rgba(255, 127, 0, 0)
      <td>0, 0, 0, 0
      <td>255, 127, 0, 0
      <td>Fully-transparent ("invisible") orange
      <td><img alt="An empty background with nothing atop it" src=images/premultiplied-example-5.html width=96 height=96>
     <tr><td>rgba(0, 127, 255, 0)
      <td>0, 0, 0, 0
      <td>255, 127, 0, 0
      <td>Fully-transparent ("invisible") turquoise
      <td><img alt="An empty background with nothing atop it" src=images/premultiplied-example-5.html width=96 height=96>
   </table>
  </div>

  <p><dfn id=convert-to-premultiplied>Converting a color value from a non-premultiplied
  representation to a premultiplied one</dfn> involves multiplying the color's red, green, and
  blue components by its alpha component (remapping the range of the alpha component such that
  "fully transparent" is 0, and "fully opaque" is 1).</p>

  <p><dfn id=convert-from-premultiplied>Converting a color value from a premultiplied
  representation to a non-premultiplied one</dfn> involves the inverse: dividing the color's red,
  green, and blue components by its alpha component.</p>

  <p>As certain colors can only be represented under premultiplied alpha (for instance, additive
  colors), and others can only be represented under non-premultiplied alpha (for instance,
  "invisible" colors which hold certain red, green, and blue values even with no opacity); and
  division and multiplication using finite precision entails a loss of accuracy, converting between
  premultiplied and non-premultiplied alpha is a lossy operation on colors that are not fully
  opaque.</p>

  <p>A <code>CanvasRenderingContext2D</code>'s <a href=#output-bitmap id=premultiplied-alpha-and-the-2d-rendering-context:output-bitmap>output bitmap</a> and an
  <code>OffscreenCanvasRenderingContext2D</code>'s <a href=#output-bitmap id=premultiplied-alpha-and-the-2d-rendering-context:output-bitmap-2>output bitmap</a> must use premultiplied
  alpha to represent transparent colors.</p>

  <p class=note>It is important for canvas bitmaps to represent colors using premultiplied alpha
  because it affects the range of representable colors. While additive colors cannot currently be
  drawn onto canvases directly because CSS colors are non-premultiplied and cannot represent them,
  it is still possible to, for instance, draw additive colors onto a WebGL canvas and then draw that
  WebGL canvas onto a 2D canvas via <code id=premultiplied-alpha-and-the-2d-rendering-context:dom-context-2d-drawimage><a href=#dom-context-2d-drawimage>drawImage()</a></code>.</p>

  <nav><a href=scripting.html>← 4.12 Scripting</a> — <a href=index.html>Table of Contents</a> — <a href=custom-elements.html>4.13 Custom elements →</a></nav>
